Compare commits

...

39 Commits

Author SHA1 Message Date
Robert Schmidt
f4d8ecbf85 IPv4v6 comment 2024-07-17 08:18:56 +02:00
Robert Schmidt
701bd2d468 Revert ip rule removal 2024-07-17 08:16:59 +02:00
Robert Schmidt
2047f45707 fixup 2024-07-17 08:16:18 +02:00
Robert Schmidt
05b2ea1344 Remove LFDS credit: we don't use it anymore 2024-07-17 08:16:13 +02:00
Robert Schmidt
8cb97ada78 Remove unused pdcp_netlink.c file 2024-07-17 08:16:06 +02:00
Robert Schmidt
4240807600 Remove --nokrnmod option, as we never use the kernel anyway 2024-07-17 08:16:01 +02:00
Robert Schmidt
1ef5b00f68 nas_config(): indicate IP version 2024-07-17 08:03:22 +02:00
Robert Schmidt
41c7b7f990 fixup drivers 2024-07-17 08:03:22 +02:00
Robert Schmidt
e919e7dc4c Remove unnecessary includes 2024-07-13 10:28:47 +02:00
Robert Schmidt
b825eceb9d Remove rb_config: not needed? 2024-07-12 18:02:06 +02:00
Robert Schmidt
a7a61eff74 Remove legacy 4G kernel modules: can we remove rb_tool? 2024-07-12 17:44:46 +02:00
Robert Schmidt
72ac07ac92 VERIFY: remove netlink/PDCP_USE_NETLINK 2024-07-12 17:33:43 +02:00
Robert Schmidt
359b92af3b Unused makefile 2024-07-12 17:12:14 +02:00
Robert Schmidt
0ec3b79da9 Linux kernel defines name length as IFNAM_SIZE, it seems no null-byte needed? 2024-07-12 17:03:55 +02:00
Robert Schmidt
043585362b nas_config(): provide entire IP address to configure
Prior to this commit, there was a global variable baseNetAddress that
could be set independently through a setter and also through the
configuration module. This baseNetAddress (16 bits IPv4) would then be
complemented with two more bytes in nas_config().

However, this is counter-productive, as not only we have a global
variable that is avoidable (we can give the entire address to
nas_config() directly), but it also would not work with IPv6. Hence,
modify to give nas_config() the entire address. A follow-up commit will
add IPv6 support.
2024-07-12 17:03:55 +02:00
Robert Schmidt
e64210fe72 Refactor setInterfaceParameter() and bringInterfaceUp()
- refactor functions to make them shorter
- provide doxygen strings
- open socket for operation once instead of in each function
- use named constant (from enum) to differentiate interface UP/DOWN
2024-07-12 17:03:54 +02:00
Robert Schmidt
6e59ea88b6 Remove netmask(): not used, UE does not need 2024-07-12 17:03:54 +02:00
Robert Schmidt
456ad6d205 nas_config(): remove broadcast parameter
Remove the broadcast address from the UE, as logically, a UE has nothing
to broadcast: it can only directly talk to the core. Additionally, at
least as of now, the UE interface is shown as "POINTOPOINT", so
broadcasting is not possible.
2024-07-12 17:03:54 +02:00
Robert Schmidt
bc777ef5db Remove unused code from nas_config.c
Remove unused header includes, as well as the test program (which does
not do much, and certainly does not test in the way we use the
interfaces).
2024-07-12 17:03:54 +02:00
Robert Schmidt
5ee4fba22d nas_config_mbms() and nas_config() do the same 2024-07-12 17:03:54 +02:00
Robert Schmidt
93ea132d50 Remove (wrong) routing table init in nas_config()
introduced in commit c70aa4c43a

describe why wrong, and why it is unclear
2024-07-12 17:03:54 +02:00
Robert Schmidt
e965c2ba3c nas_config_mbms/netlink_init_mbms_tun(): use entire interface prefix
Does the same change in the _mbms() functions as in the previous commit.

Also, simplify logic in netlink_init_mbms_tun(): directly use the id in
the interface.
2024-07-12 17:03:54 +02:00
Robert Schmidt
8c50c7d464 nas_config()/netlink_init_tun(): use entire interface name (prefix)
Instead of implicitly using a hardcoded prefix "oaitun_" interface
name, move that out to the callers of these functions to make it clear.
The ID still remains outside.

The "sister functions" nas_config_mbms()/netlink_init_tun_mbms() will do
the same change in the next commit.
2024-07-12 17:03:54 +02:00
Robert Schmidt
814d546989 4G RLC/PDCP interface: remove function pointers
Remove function pointers that were used in the past to implement the
F1(-U) interface in 4G, i.e., to have different functions to handle
split/monolithic operations. As we don't have F1 in 4G anymore (see
commit 9dc2282249), we don't need the
function pointers anymore.

On that occasion, rename the 5G functions by prepending nr_ to them;
this allows to refactor the interface in 5G further (which is not the
focus of this changeset).
2024-07-12 17:03:53 +02:00
Robert Schmidt
c851489ab5 Add const to parameters to setInterfaceParameter()
The passed parameters are not modified, so use const to signal this to
users.
2024-07-12 16:21:09 +02:00
Robert Schmidt
0ea9517034 Replace nas_config_mbms_s1() call with nas_config_mbms()
Comparing both functions, it seems that nas_config_mbms_s1() sets the
same parameters, assuming that in nas_config_mbms(), we set
- (UE_NAS_USE_TUN || ENB_NAS_USE_TUN) yielding true -> should yield the
  same interface name
- netmask is hardcoded to 255.255.255.0
- baseNetAddress is hardcoded 10.0

So remove the call with nas_config_mbms() by setting parameters
accordingly.
2024-07-12 16:21:09 +02:00
Robert Schmidt
f08dea3b16 Make functions used only in module static 2024-07-12 16:21:09 +02:00
Robert Schmidt
cb8597fd9f Remove unused broadcast functionality
functions setBroadcastAddress() and getBroadcastAddress(), as well as
global variable broadcastAddr are not used in consumers. Remove it.
2024-07-12 16:21:09 +02:00
Robert Schmidt
7091e19370 Remove unused functions getNetMask() 2024-07-12 16:21:09 +02:00
Robert Schmidt
61ca3ec1cb Remove unused blocking_NAS_config() 2024-07-12 16:21:09 +02:00
Robert Schmidt
9b1be04bed Remove unused set_gateway() 2024-07-12 16:21:09 +02:00
Robert Schmidt
c5ac44a8ef Remove unused NAS_config()
It does most of what the highly similar nas_config() does. It is not
used anywhere.
2024-07-12 16:21:09 +02:00
Robert Schmidt
16bd5c936d Remove unused SIMULATION/ETH_TRANSPORT/defs.h 2024-07-12 16:21:09 +02:00
Robert Schmidt
de33ecac01 remove multicast_link.* 2024-07-12 16:21:09 +02:00
Robert Schmidt
28238d84c8 Remove multicast: code is not used in current scenarios 2024-07-12 16:21:08 +02:00
Robert Schmidt
91f1f8b054 Remove rb_config functions from nas_config, remove unused functions, make static 2024-07-12 16:21:08 +02:00
Robert Schmidt
d3bec3c5b1 Remove unused code in openair3/UTILS: not used anywhere 2024-07-12 16:21:08 +02:00
Robert Schmidt
fe01add11f Remove unused code in ETH_TRANSPORT/socket.{ch} 2024-07-12 16:21:08 +02:00
Robert Schmidt
592a396b3a Remove unused emu_transport.c 2024-07-12 16:21:08 +02:00
104 changed files with 266 additions and 16115 deletions

View File

@@ -508,9 +508,6 @@ include_directories ("${OPENAIR_DIR}/radio/COMMON")
# ???!!! TO BE DOCUMENTED OPTIONS !!!???
##############################################################
add_boolean_option(OAI_NW_DRIVER_TYPE_ETHERNET False "????" ON)
add_boolean_option(OAI_NW_DRIVER_USE_NETLINK True "????" ON)
add_boolean_option(UE_EXPANSION False "enable UE_EXPANSION with max 256 UE" ON)
add_boolean_option(PHY_TX_THREAD False "enable UE_EXPANSION with max 256 UE" ON)
add_boolean_option(PRE_SCD_THREAD False "enable UE_EXPANSION with max 256 UE" ON)
@@ -1483,10 +1480,6 @@ add_library(L2_UE_LTE_NR
)
target_link_libraries(L2_UE_LTE_NR PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
if (NOT ${NOS1})
target_compile_definitions(L2_UE PUBLIC -DPDCP_USE_NETLINK)
endif()
target_link_libraries(L2_UE PRIVATE asn1_lte_rrc_hdrs)
add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} )
@@ -1902,8 +1895,6 @@ endif()
add_library(SIMU_ETH STATIC
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c
)
target_link_libraries(SIMU_ETH PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
@@ -1956,7 +1947,6 @@ add_executable(lte-softmodem
${OPENAIR_DIR}/radio/COMMON/common_lib.c
${OPENAIR_DIR}/radio/COMMON/record_player.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
${PHY_INTERFACE_DIR}/queue_t.c
${OPENAIR_DIR}/common/utils/lte/ue_power.c
@@ -2014,16 +2004,12 @@ add_executable(lte-uesoftmodem
${OPENAIR_DIR}/radio/COMMON/common_lib.c
${OPENAIR_DIR}/radio/COMMON/record_player.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
${OPENAIR_DIR}/common/utils/lte/ue_power.c
${OPENAIR_DIR}/common/utils/lte/prach_utils.c
${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c
)
if (NOT ${NOS1})
target_compile_definitions(lte-uesoftmodem PRIVATE -DPDCP_USE_NETLINK)
endif()
target_link_libraries(lte-uesoftmodem PRIVATE
-Wl,--start-group
lte_rrc nr_rrc s1ap x2ap m2ap m3ap
@@ -2054,7 +2040,6 @@ add_executable(nr-softmodem
${OPENAIR_DIR}/radio/COMMON/common_lib.c
${OPENAIR_DIR}/radio/COMMON/record_player.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR_DIR}/common/utils/lte/ue_power.c
${OPENAIR_DIR}/common/utils/lte/prach_utils.c
${PHY_INTERFACE_DIR}/queue_t.c
@@ -2126,7 +2111,6 @@ add_executable(nr-uesoftmodem
${OPENAIR_DIR}/radio/COMMON/record_player.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c
)
@@ -2359,7 +2343,7 @@ endforeach(myExe)
#ensure that the T header files are generated before targets depending on them
if (${T_TRACER})
foreach(i
#all "add_executable" definitions (except tests, rb_tool, updatefw)
#all "add_executable" definitions (except tests, updatefw)
lte-softmodem lte-uesoftmodem nr-softmodem
nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7
ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim
@@ -2382,86 +2366,6 @@ if (${T_TRACER})
endforeach(i)
endif (${T_TRACER})
##################################################
# Generated specific cases is not regular code
###############################################
################
# Kernel modules
###############
# Set compiler options for kernel modules
# we need to get out cmake to use the regular Linux Kernel process
# this is documented as https://www.kernel.org/doc/Documentation/kbuild/modules.txt
######################################
# retrieve the compiler options to send it to gccxml
get_directory_property(DirDefs COMPILE_DEFINITIONS )
foreach( d ${DirDefs} )
set(module_cc_opt "${module_cc_opt} -D${d}")
endforeach()
get_directory_property( DirDefs INCLUDE_DIRECTORIES )
foreach( d ${DirDefs} )
set(module_cc_opt "${module_cc_opt} -I${d}")
endforeach()
EXECUTE_PROCESS(COMMAND uname -r
OUTPUT_VARIABLE os_release
OUTPUT_STRIP_TRAILING_WHITESPACE)
SET(module_build_path /lib/modules/${os_release}/build)
function(make_driver name dir)
file(MAKE_DIRECTORY ${OPENAIR_BIN_DIR}/${name})
foreach(f IN ITEMS ${ARGN})
list(APPEND src_path_list ${dir}/${f})
string(REGEX REPLACE "c *$" "o" obj ${f})
set(objs "${objs} ${obj}")
endforeach()
CONFIGURE_FILE(${OPENAIR_CMAKE}/tools/Kbuild.cmake ${OPENAIR_BIN_DIR}/${name}/Kbuild)
add_custom_command(OUTPUT ${name}.ko
COMMAND make -C ${module_build_path} M=${OPENAIR_BIN_DIR}/${name}
WORKING_DIRECTORY ${OPENAIR_BIN_DIR}/${name}
COMMENT "building ${module}.ko"
VERBATIM
SOURCES ${src_path_list}
)
add_custom_target(${name} DEPENDS ${name}.ko)
endfunction(make_driver name dir src)
# nashmesh module
################
list(APPEND nasmesh_src device.c common.c ioctl.c classifier.c tool.c mesh.c)
set(module_cc_opt "${module_cc_opt} -DNAS_NETLINK -DPDCP_USE_NETLINK")
# legacy Makefile was using NAS_NETLINK flag, but other drivers the hereafter flag
# so, this cmake use OAI_NW_DRIVER_USE_NETLINK everywhere
if (OAI_NW_DRIVER_USE_NETLINK)
list(APPEND nasmesh_src netlink.c)
endif()
make_driver(nasmesh ${OPENAIR2_DIR}/NETWORK_DRIVER/MESH ${nasmesh_src})
# user space tool for configuring MESH IP driver
################
add_executable(rb_tool
${OPENAIR2_DIR}/NETWORK_DRIVER/MESH/RB_TOOL/rb_tool.c
)
target_include_directories(rb_tool PRIVATE ${OPENAIR2_DIR}/NETWORK_DRIVER/MESH/)
# ???
####################
list(APPEND oai_nw_drv_src device.c common.c ioctl.c classifier.c tool.c)
if(OAI_NW_DRIVER_USE_NETLINK)
list(APPEND oai_nw_drv_src netlink.c)
endif()
make_driver(oai_nw_drv ${OPENAIR2_DIR}/NETWORK_DRIVER/LTE ${oai_nw_drv_src})
# ue_ip: purpose ???
###############
list(APPEND ue_ip_src device.c common.c)
if(OAI_NW_DRIVER_USE_NETLINK)
list(APPEND ue_ip_src netlink.c)
endif()
make_driver(ue_ip ${OPENAIR2_DIR}/NETWORK_DRIVER/UE_IP ${ue_ip_src})
include(${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/CMakeLists.txt)
set(ENABLE_TESTS OFF CACHE STRING "Activate build of tests")

View File

@@ -4,15 +4,6 @@ For more details of the license, refer to [LICENSE](LICENSE) file in the same di
However, the source code also contains third party software that is acknowledged here for reference.
## Credits for LFDS user space source code located in folder openair2/UTILS/LFDS/ ##
See on [liblfds website](https://liblfds.org/) the license section.
<pre>
"There is no license. You are free to use this software in any way, for any purpose. Go forth and create wealth!
If however for legal reasons a licence is required, the license of your choice will be granted."
</pre>
## Credits for source code common/utils/collection/queue.h: ##
The Regents of the University of California: BSD 3-Clause Licence.

View File

@@ -85,7 +85,7 @@ Options:
--RU
Makes the OAI RRU
--UE
Makes the UE specific parts (ue_ip, usim, nvram) from the given configuration file
Makes the UE specific parts (usim, nvram) from the given configuration file
--nrUE
Makes the NR UE softmodem
--UE-conf-nvram [configuration file]
@@ -271,9 +271,6 @@ function main() {
--UE-gen-nvram)
gen_nvram_path=$(readlink -f "$2")
shift 2;;
--UE-ip)
TARGET_LIST="$TARGET_LIST ue_ip"
shift;;
-w | --hardware)
case "$2" in
"USRP" | "BLADERF" | "LMSSDR" | "IRIS")

View File

@@ -171,10 +171,6 @@ clean_kernel() {
$SUDO iptables -t filter -F
$SUDO iptables -t raw -F
echo_info "Flushed iptables"
$SUDO rmmod nasmesh > /dev/null 2>&1
$SUDO rmmod oai_nw_drv > /dev/null 2>&1
$SUDO rmmod ue_ip > /dev/null 2>&1
echo_info "removed drivers from kernel"
}
clean_all_files() {

View File

@@ -1,54 +0,0 @@
#!/bin/bash
#/*
# * 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
# */
# file init_nas_nos1
# brief loads the nasmesh module and sets up the radio bearers (used to provide ip interface without S1 interface)
# author Florian Kaltenberger
#
#######################################
load_module() {
mod_name=${1##*/}
mod_name=${mod_name%.*}
if awk "/$mod_name/ {found=1 ;exit} END {if (found!=1) exit 1}" /proc/modules
then
echo "module $mod_name already loaded: I remove it first"
sudo rmmod $mod_name
fi
echo loading $mod_name
sudo insmod $1
}
load_module $OPENAIR_DIR/cmake_targets/ran_build/build/nasmesh.ko
if [ "$1" = "eNB" ]; then
echo "bring up oai0 interface for enb"
sudo ifconfig oai0 10.0.1.1 netmask 255.255.255.0 broadcast 10.0.1.255
$OPENAIR_DIR/cmake_targets/ran_build/build/rb_tool -a -c0 -i0 -z0 -s 10.0.1.1 -t 10.0.1.2 -r 1
else
if [ "$1" = "UE" ]; then
echo "bring up oai0 interface for UE"
sudo ifconfig oai0 10.0.1.2 netmask 255.255.255.0 broadcast 10.0.1.255
$OPENAIR_DIR/cmake_targets/ran_build/build/rb_tool -a -c0 -i0 -z0 -s 10.0.1.2 -t 10.0.1.1 -r 1
fi
fi

View File

@@ -1,71 +0,0 @@
#!/bin/bash
#WARNING: this file may not work properly, be sure to know what you
#do when using it
#/*
# * 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
# */
################################################################################
# file init_nas_s1
# brief loads the ue_ip module and sets up IP for the UE
# you may want to edit it to fit your settings (replace oip0 by oipX for
# instance)
# author Florian Kaltenberger
#
#######################################
LTEIF=oip1
#OPENAIR_DIR=/home/oai/svn-oai/openair4G
load_module() {
mod_name=${1##*/}
mod_name=${mod_name%.*}
if awk "/$mod_name/ {found=1 ;exit} END {if (found!=1) exit 1}" /proc/modules
then
echo "module $mod_name already loaded: I remove it first"
sudo rmmod $mod_name
fi
echo loading $mod_name
sudo insmod $1
}
load_module ../ran_build/build/ue_ip.ko
if [ "$1" = "UE" ]; then
echo "bring up $LTEIF interface for UE"
sudo ifconfig $LTEIF up
fi
sudo ip route flush cache
sleep 1
sudo sysctl -w net.ipv4.conf.all.log_martians=1
echo "Disabling reverse path filtering"
sudo sysctl -w net.ipv4.conf.all.rp_filter=0
sudo ip route flush cache
# Check table 200 lte in /etc/iproute2/rt_tables
fgrep lte /etc/iproute2/rt_tables > /dev/null
if [ $? -ne 0 ]; then
echo "200 lte " >> /etc/iproute2/rt_tables
fi
sudo ip rule add fwmark 1 table lte
sudo ip route add default dev $LTEIF table lte

View File

@@ -69,7 +69,6 @@ To get help on supported parameters you can use specific options:
--worker-config: two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'
--nbiot-disable: disable nb-iot, even if defined in config
--noS1: Disable s1 interface
--nokrnmod: (noS1 only): Use tun instead of namesh module
--------------------------------------------------------------------
[LIBCONFIG] (root): 4/4 parameters successfully set, (4 to default value)

View File

@@ -38,7 +38,6 @@ Running the [build_oai](../cmake_targets/build_oai) script also generates some
- `conf2uedata`: a binary used to build the (4G) UE data from a configuration file. The created file emulates the sim card of a 3GPP compliant phone.
- `nvram`: a binary used to build (4G) UE (IMEI...) and EMM (IMSI, registered PLMN) non volatile data.
- `rb_tool`: radio bearer utility for (4G) UE
- `genids` T Tracer utility, used at build time to generate `T_IDs.h` include file. This binary is located in the [T Tracer source file directory](../common/utils/T) .
The build system for OAI uses [cmake](https://cmake.org/) which is a tool to generate makefiles. The `build_oai` script is a wrapper using `cmake` and `make`/`ninja` to ease the oai build and use. It logs the `cmake` and `ninja`/`make` commands it executes. The file describing how to build the executables from source files is the [CMakeLists.txt](../CMakeLists.txt), it is used as input by cmake to generate the makefiles.

View File

@@ -1874,8 +1874,6 @@ INPUT = \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR_UE/rrc_defs.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR_UE/L2_interface_ue.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NAS/rb_config.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NAS/rb_config.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NAS/nas_config.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NAS/nas_config.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/rrc_gNB_internode.c \
@@ -2310,12 +2308,7 @@ INPUT = \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SIMULATION/ETH_TRANSPORT/proto.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SIMULATION/ETH_TRANSPORT/multicast_link.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SIMULATION/ETH_TRANSPORT/socket.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SIMULATION/ETH_TRANSPORT/socket.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SIMULATION/ETH_TRANSPORT/defs.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SIMULATION/RF/adc.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SIMULATION/RF/dac.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SIMULATION/RF/rf.h \

View File

@@ -45,7 +45,7 @@ $ source oaienv
$ cd cmake_targets/tools
$ sudo -E ./init_nas_nos1 eNB
$ cd ../ran_build/build
$ sudo -E ./lte-softmodem -O YYY.conf --noS1 --nokrnmod 0
$ sudo -E ./lte-softmodem -O YYY.conf --noS1
```
# How to run a UE with the noS1 option
@@ -59,7 +59,7 @@ $ source oaienv
$ cd cmake_targets/tools
$ sudo -E ./init_nas_nos1 UE
$ cd ../ran_build/build
$ sudo ./lte-uesoftmodem -O XXX.conf -r 25 --siml1 --noS1 --nokrnmod 0
$ sudo ./lte-uesoftmodem -O XXX.conf -r 25 --siml1 --noS1
```
That should give you equivalent functionality to what you had with oaisim including noise and RF channel emulation (path loss / fading, etc.). You should also be able to run multiple UEs.

View File

@@ -33,7 +33,7 @@ than the value of `--subframes-max` parameter.
>Recording session example:
```bash
./nr-uesoftmodem -O /home/oaitests/mediatek_sim.conf --sa --nokrnmod 1 --numerology 1 -r 106 -C 3649440000 --band 78 -E --ue-fo-compensation --device.recplay.subframes-record 1 --device.recplay.subframes-file /home/iqs/oai-nrUE-17042023.dat --device.recplay.use-mmap 1 --device.recplay.subframes-max 30000
./nr-uesoftmodem -O /home/oaitests/mediatek_sim.conf --sa --numerology 1 -r 106 -C 3649440000 --band 78 -E --ue-fo-compensation --device.recplay.subframes-record 1 --device.recplay.subframes-file /home/iqs/oai-nrUE-17042023.dat --device.recplay.use-mmap 1 --device.recplay.subframes-max 30000
............................................
............................................
............................................
@@ -54,7 +54,7 @@ options for replay mode are:
>Replay mode session example:
```bash
./nr-uesoftmodem -O /home/oaitests/mediatek_sim.conf --sa --nokrnmod 1 --numerology 1 -r 106 -C 3649440000 --band 78 -E --ue-fo-compensation --device.recplay.subframes-replay 1 --device.recplay.subframes-file /home/iqs/oai-nrUE-17042023.dat --device.recplay.use-mmap 1 --device.recplay.subframes-loops 1
./nr-uesoftmodem -O /home/oaitests/mediatek_sim.conf --sa --numerology 1 -r 106 -C 3649440000 --band 78 -E --ue-fo-compensation --device.recplay.subframes-replay 1 --device.recplay.subframes-file /home/iqs/oai-nrUE-17042023.dat --device.recplay.use-mmap 1 --device.recplay.subframes-loops 1
..................................
..................................
[HW] Replay iqs from USRP B200 device, bandwidth 4.000000e+07

View File

@@ -410,18 +410,14 @@ extern void phy_free_RU(RU_t *);
static void init_pdcp(void)
{
pdcp_layer_init();
uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ?
(PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT;
uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ? LINK_ENB_PDCP_TO_IP_DRIVER_BIT : LINK_ENB_PDCP_TO_GTPV1U_BIT;
if (IS_SOFTMODEM_NOS1)
pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ;
pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT;
pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_W_MBMS_BIT;
pdcp_module_init(pdcp_initmask, 0);
pdcp_set_rlc_data_req_func(rlc_data_req);
pdcp_set_pdcp_data_ind_func(pdcp_data_ind);
}
static void wait_nfapi_init(char *thread_name) {

View File

@@ -80,11 +80,6 @@ void init_UE_threads_stub(int);
void init_UE_single_thread_stub(int);
void *UE_thread(void *arg);
int init_timer_thread(void);
extern void multicast_link_start(void (*rx_handlerP) (unsigned int, char *),
unsigned char _multicast_group,
char *multicast_ifname);
extern int multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP);
int tx_req_num_elems;
extern uint16_t sf_ahead;
@@ -364,10 +359,9 @@ void init_UE_stub_single_thread(int nb_inst,
init_UE_single_thread_stub(nb_inst);
printf("UE threads created \n");
if(NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF) {
LOG_I(PHY,"Starting multicast link on %s\n",emul_iface);
multicast_link_start(ue_stub_rx_handler,0,emul_iface);
}
AssertFatal(NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF,
"unsupported NFAPI mode %d\n",
NFAPI_MODE);
}
void init_UE_standalone_thread(int ue_idx) {
@@ -408,8 +402,9 @@ void init_UE_stub(int nb_inst,
printf("UE threads created \n");
LOG_I(PHY,"Starting multicast link on %s\n",emul_iface);
if(NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF)
multicast_link_start(ue_stub_rx_handler,0,emul_iface);
AssertFatal(NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF,
"unsupported NFAPI mode %d\n",
NFAPI_MODE);
}
@@ -2356,15 +2351,7 @@ static void *timer_thread( void *param ) {
}
nanosleep(&t_sleep, (struct timespec *)NULL);
UE_tport_t pdu;
pdu.header.packet_type = TTI_SYNC;
pdu.header.absSF = (timer_frame*10)+timer_subframe;
if (NFAPI_MODE != NFAPI_UE_STUB_PNF && NFAPI_MODE != NFAPI_MODE_STANDALONE_PNF) {
multicast_link_write_sock(0,
(char *)&pdu,
sizeof(UE_tport_header_t));
}
AssertFatal(NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF, "unsupported NFAPI mode %d\n", NFAPI_MODE);
} else {
wait_on_condition(&UE->timer_mutex,&UE->timer_cond,&UE->instance_cnt_timer,"timer_thread");
release_thread(&UE->timer_mutex,&UE->instance_cnt_timer,"timer_thread");

View File

@@ -491,18 +491,18 @@ static inline void wait_nfapi_init(char *thread_name) {
}
static void init_pdcp(int ue_id) {
uint32_t pdcp_initmask = (!IS_SOFTMODEM_NOS1) ? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT);
uint32_t pdcp_initmask = (!IS_SOFTMODEM_NOS1) ? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT);
if (IS_SOFTMODEM_RFSIM || (nfapi_getmode()==NFAPI_UE_STUB_PNF)) {
pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT;
}
if (IS_SOFTMODEM_NOKRNMOD)
pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT;
// code previously checked for IS_SOFTMODEM_NOKRNMOD which was practically
// always set (we never used kernel modules). Leave the current flag enabled;
// further refactoring could take it out
pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT;
pdcp_module_init(pdcp_initmask, ue_id);
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
}
// Stupid function addition because UE itti messages queues definition is common with eNB

View File

@@ -105,7 +105,6 @@
#define CONFIG_HLP_TELN "Start embedded telnet server \n"
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n"
#define CONFIG_HLP_NOS1 "Disable s1 interface\n"
#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n"
/*--------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters for LOG utility */

View File

@@ -547,7 +547,7 @@ static void wait_nfapi_init(char *thread_name) {
void init_pdcp(void) {
uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ?
PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT:
LINK_ENB_PDCP_TO_IP_DRIVER_BIT | ENB_NAS_USE_TUN_BIT :
LINK_ENB_PDCP_TO_GTPV1U_BIT;
if (!NODE_IS_DU(get_node_type())) {
@@ -658,12 +658,7 @@ int main( int argc, char **argv ) {
itti_init(TASK_MAX, tasks_info);
// initialize mscgen log after ITTI
init_opt();
if(PDCP_USE_NETLINK && !IS_SOFTMODEM_NOS1) {
netlink_init();
if (get_softmodem_params()->nsa) {
init_pdcp();
}
}
#ifndef PACKAGE_VERSION
#define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
#endif

View File

@@ -373,22 +373,22 @@ void init_openair0()
static void init_pdcp(int ue_id)
{
uint32_t pdcp_initmask = (!IS_SOFTMODEM_NOS1) ? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT);
uint32_t pdcp_initmask = (!IS_SOFTMODEM_NOS1) ? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT);
/*if (IS_SOFTMODEM_RFSIM || (nfapi_getmode()==NFAPI_UE_STUB_PNF)) {
pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT;
}*/
if (IS_SOFTMODEM_NOKRNMOD) {
pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT;
}
// code previously checked for IS_SOFTMODEM_NOKRNMOD which was practically
// always set (we never used kernel modules). Leave the current flag enabled;
// further refactoring could take it out
pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT;
if (get_softmodem_params()->nsa && rlc_module_init(0) != 0) {
LOG_I(RLC, "Problem at RLC initiation \n");
}
nr_pdcp_layer_init(false);
nr_pdcp_module_init(pdcp_initmask, ue_id);
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
}
// Stupid function addition because UE itti messages queues definition is common with eNB

View File

@@ -97,7 +97,7 @@ void get_common_options(configmodule_interface_t *cfg, uint32_t execmask)
uint32_t glog_level=0 ;
uint32_t start_telnetsrv = 0, start_telnetclt = 0;
uint32_t start_websrv = 0;
uint32_t noS1 = 0, nokrnmod = 1, nonbiot = 0;
uint32_t noS1 = 0, nonbiot = 0;
uint32_t rfsim = 0, do_forms = 0, do_forms_qt = 0;
int nfapi_index = 0;
char *logmem_filename = NULL;
@@ -146,10 +146,6 @@ void get_common_options(configmodule_interface_t *cfg, uint32_t execmask)
set_softmodem_optmask(SOFTMODEM_NOS1_BIT);
}
if (nokrnmod) {
set_softmodem_optmask(SOFTMODEM_NOKRNMOD_BIT);
}
if (nonbiot) {
set_softmodem_optmask(SOFTMODEM_NONBIOT_BIT);
}

View File

@@ -100,7 +100,6 @@ extern "C"
#define CONFIG_HLP_NOS1 "Disable s1 interface\n"
#define CONFIG_HLP_RFSIM "Run in rf simulator mode\n"
#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n"
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
#define CONFIG_HLP_USRP_THREAD "having extra thead for usrp tx\n"
#define CONFIG_HLP_NFAPI "Change the nFAPI mode for NR 'MONOLITHIC', 'PNF', 'VNF', 'AERIAL','UE_STUB_PNF','UE_STUB_OFFNET','STANDALONE_PNF'\n"
@@ -177,7 +176,6 @@ extern int usrp_tx_thread;
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, .strptr=&worker_config, .defstrval=NULL, TYPE_STRING, 0}, \
{"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, .uptr=&noS1, .defintval=0, TYPE_UINT, 0}, \
{"rfsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, .uptr=&rfsim, .defintval=0, TYPE_UINT, 0}, \
{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, .uptr=&nokrnmod, .defintval=1, TYPE_UINT, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, .uptr=&nonbiot, .defuintval=0, TYPE_UINT, 0}, \
{"chest-freq", CONFIG_HLP_CHESTFREQ, 0, .iptr=&CHEST_FREQ, .defintval=0, TYPE_INT, 0}, \
{"chest-time", CONFIG_HLP_CHESTTIME, 0, .iptr=&CHEST_TIME, .defintval=0, TYPE_INT, 0}, \
@@ -230,7 +228,6 @@ extern int usrp_tx_thread;
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s3a = { config_checkstr_assign_integer, \
{"MONOLITHIC", "PNF", "VNF", "AERIAL","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \
{NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF, NFAPI_MODE_AERIAL,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \
@@ -284,7 +281,6 @@ extern int usrp_tx_thread;
/***************************************************************************************************************************************/
#define SOFTMODEM_NOS1_BIT (1<<0)
#define SOFTMODEM_NOKRNMOD_BIT (1<<1)
#define SOFTMODEM_NONBIOT_BIT (1<<2)
#define SOFTMODEM_RFSIM_BIT (1<<10)
#define SOFTMODEM_SIML1_BIT (1<<12)
@@ -305,7 +301,6 @@ extern int usrp_tx_thread;
#define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT)
#define IS_SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT)
#define IS_SOFTMODEM_NONBIOT ( get_softmodem_optmask() & SOFTMODEM_NONBIOT_BIT)
#define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT)
#define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT)

View File

@@ -31,8 +31,6 @@
*/
#include "PHY/defs_UE.h"
extern int multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP);
void generate_sldch(PHY_VARS_UE *ue,SLDCH_t *sldch,int frame_tx,int subframe_tx) {
UE_tport_t pdu;
@@ -54,10 +52,5 @@ void generate_sldch(PHY_VARS_UE *ue,SLDCH_t *sldch,int frame_tx,int subframe_tx)
sldch->payload_length,
sldch_header_len+sizeof(SLDCH_t)-sizeof(uint8_t*)+sldch->payload_length);
multicast_link_write_sock(0,
(char *)&pdu,
sldch_header_len+sizeof(SLDCH_t));
AssertFatal(false, "multicast_link_write_sock() not implemented\n");
}

View File

@@ -31,10 +31,6 @@
*/
#include "PHY/defs_UE.h"
extern int
multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP);
void generate_slsch(PHY_VARS_UE *ue,SLSCH_t *slsch,int frame_tx,int subframe_tx) {
UE_tport_t pdu;
@@ -58,9 +54,6 @@ void generate_slsch(PHY_VARS_UE *ue,SLSCH_t *slsch,int frame_tx,int subframe_tx)
slsch->payload_length,
slsch_header_len+sizeof(SLSCH_t)-sizeof(uint8_t*)+slsch->payload_length);
multicast_link_write_sock(0,
(char *)&pdu,
slsch_header_len+sizeof(SLSCH_t)-sizeof(uint8_t*)+slsch->payload_length);
AssertFatal(false, "multicast_link_write_sock() not implemented\n");
}
}

View File

@@ -706,5 +706,4 @@ typedef struct LDPCDecode_ue_s {
UE_nr_rxtx_proc_t proc;
} ldpcDecode_ue_t;
#include "SIMULATION/ETH_TRANSPORT/defs.h"
#endif

View File

@@ -1,6 +0,0 @@
ETHERNET_TRANSPORT_OBJS = $(TOP_DIR)/SIMULATION/ETH_TRANSPORT/netlink_init.o
ETHERNET_TRANSPORT_OBJS += $(TOP_DIR)/SIMULATION/ETH_TRANSPORT/multicast_link.o
ETHERNET_TRANSPORT_OBJS += $(TOP_DIR)/SIMULATION/ETH_TRANSPORT/socket.o
ETHERNET_TRANSPORT_OBJS += $(TOP_DIR)/SIMULATION/ETH_TRANSPORT/bypass_session_layer.o
ETHERNET_TRANSPORT_OBJS += $(TOP_DIR)/SIMULATION/ETH_TRANSPORT/emu_transport.o
ETHERNET_TRANSPORT_OBJS += $(TOP_DIR)/SIMULATION/ETH_TRANSPORT/pgm_link.o

View File

@@ -1,144 +0,0 @@
/*
* 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
*/
/*! \file defs.h
* \brief specifies the data structure and variable for phy emulation
* \author Navid Nikaein, Raymomd Knopp and Hicham Anouar
* \date 2011
* \version 1.1
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
*/
#ifndef __BYPASS_SESSION_LAYER_DEFS_H__
# define __BYPASS_SESSION_LAYER_DEFS_H__
//-----------------------------------------------------------------------------
//#include "openair_defs.h"
#include "common/openairinterface5g_limits.h"
#include "PHY/defs_common.h"
#include "PHY/LTE_TRANSPORT/uci_common.h"
typedef enum emu_transport_info_e {
EMU_TRANSPORT_INFO_ERROR = 0x0,
EMU_TRANSPORT_INFO_WAIT_PM,
EMU_TRANSPORT_INFO_WAIT_SM,
EMU_TRANSPORT_INFO_SYNC,
EMU_TRANSPORT_INFO_ENB,
EMU_TRANSPORT_INFO_UE,
EMU_TRANSPORT_INFO_RELEASE
} emu_transport_info_t;
#define WAIT_PM_TRANSPORT 1
#define WAIT_SM_TRANSPORT 2
#define SYNC_TRANSPORT 3
#define ENB_TRANSPORT 4
#define UE_TRANSPORT 5
#define RELEASE_TRANSPORT 6
#define WAIT_SYNC_TRANSPORT 1
#define SYNCED_TRANSPORT 2
//#define WAIT_ENB_TRANSPORT 2
//#define WAIT_UE_TRANSPORT 3
#define BYPASS_RX_BUFFER_SIZE 64000
#define BYPASS_TX_BUFFER_SIZE 64000
typedef unsigned int (*tx_handler_t) (unsigned char, char*, unsigned int*, unsigned int*);
typedef unsigned int (*rx_handler_t) (unsigned char, char*, unsigned int);
/*************************************************************/
typedef struct eNB_cntl_s {
uint32_t pbch_flag:1;
uint32_t pmch_flag:1;
uint32_t pss:2;
uint32_t sss:8;
uint32_t cfi:2;
uint32_t phich:19; // max 200 bit
// uint32_t pbch_payload:24;
uint32_t pbch_payload;
} eNB_cntl;
typedef struct UE_cntl_s {
uint8_t pucch_flag:3; // 0,7 = none, 1 = type 1, 2=type 1a, 3=type 1b, 4=type 2, 5=type 2a, 6=type 2b
uint8_t pucch_Ncs1:3; // physical configuration of pucch, for abstraction purposes
uint32_t pucch_payload:21; // ack/nak/cqi information
uint8_t sr:1;
uint8_t pusch_flag:1; // 0=none,1=active
uint8_t pucch_sel:1;
//uint32_t pusch_uci; // uci information on pusch
uint8_t pusch_uci[MAX_CQI_BYTES];
uint8_t uci_format;
uint8_t length_uci;
uint8_t pusch_ri:2; // ri information on pusch
uint8_t pusch_ack:2; // ack/nak on pusch
uint8_t prach_flag:1; // 0=none,1=active
uint8_t prach_id:6; // this is the PHY preamble index for the prach
} UE_cntl;
#define MAX_TRANSPORT_BLOCKS_BUFFER_SIZE 16384
//#define MAX_PMCH_TRANSPORT_BLOCKS_BUFFER_SIZE 8192 // 16384
#define MAX_NUM_DCI 5+1 // +1: for PMCH/MCH
typedef struct eNB_transport_info_s {
eNB_cntl cntl;
uint8_t num_pmch;
uint8_t num_common_dci;
uint8_t num_ue_spec_dci;
DCI_ALLOC_t dci_alloc[MAX_NUM_DCI];
uint8_t dlsch_type[MAX_NUM_DCI];
uint8_t harq_pid[MAX_NUM_DCI];
uint8_t ue_id[MAX_NUM_DCI];
uint16_t tbs[MAX_NUM_DCI*2]; // times 2 for dual-stream MIMO formats
uint8_t transport_blocks[MAX_TRANSPORT_BLOCKS_BUFFER_SIZE];
//uint8_t pmch_transport_blocks[MAX_PMCH_TRANSPORT_BLOCKS_BUFFER_SIZE];
} __attribute__((__packed__)) eNB_transport_info_t ;
typedef struct UE_transport_info_s {
UE_cntl cntl;
uint8_t num_eNB;
uint16_t rnti[NUMBER_OF_CONNECTED_eNB_MAX];
uint8_t eNB_id[NUMBER_OF_CONNECTED_eNB_MAX];
uint8_t harq_pid[NUMBER_OF_CONNECTED_eNB_MAX];
uint16_t tbs[NUMBER_OF_CONNECTED_eNB_MAX];
uint8_t transport_blocks[MAX_TRANSPORT_BLOCKS_BUFFER_SIZE];//*NUMBER_OF_CONNECTED_eNB_MAX];
} __attribute__((__packed__)) UE_transport_info_t ;
/*! \brief */
typedef struct bypass_msg_header_s {
unsigned char Message_type; /*! \brief control or data*/
//unsigned char nb_master; /*! \brief */
unsigned char master_id; /*! \brief */
unsigned int nb_enb; /*! \brief */
unsigned int nb_ue; /*! \brief */
unsigned int nb_flow; /*! \brief */
unsigned int frame;
unsigned int subframe;
uint64_t seq_num;
unsigned int failing_master_id;
} __attribute__((__packed__)) bypass_msg_header_t;
typedef struct bypass_proto2multicast_header_s {
unsigned int size;
} bypass_proto2multicast_header_t;
#endif /* __BYPASS_SESSION_LAYER_DEFS_H__ */

View File

@@ -1,517 +0,0 @@
/*
* 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
*/
/*! \file phy_emulation.c
* \brief implements the underlying protocol for emulated data exchange over Ethernet using IP multicast
* \author Navid Nikaein
* \date 2011 - 2014
* \version 1.1
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
*/
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "common/ran_context.h"
#include "defs.h"
#include "extern.h"
#include "proto.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "openair1/SIMULATION/ETH_TRANSPORT/extern.h"
unsigned char Emulation_status;
unsigned char emu_tx_status;
unsigned char emu_rx_status;
#if !defined(ENABLE_NEW_MULTICAST)
pthread_mutex_t Tx_mutex;
pthread_cond_t Tx_cond;
char Tx_mutex_var;
#endif
/* Handlers for RX and TX */
rx_handler_t rx_handler;
tx_handler_t tx_handler;
eNB_transport_info_t eNB_transport_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
uint16_t eNB_transport_info_TB_index[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
UE_transport_info_t UE_transport_info[NUMBER_OF_UE_MAX][MAX_NUM_CCs];
UE_cntl ue_cntl_delay[NUMBER_OF_UE_MAX][MAX_NUM_CCs][2];
extern unsigned int Master_list_rx;
extern unsigned char NB_INST;
//#define DEBUG_CONTROL 1
//#define DEBUG_EMU 1
void emu_transport_sync(void)
{
LOG_D(EMU, "Entering EMU transport SYNC is primary master %d\n",
oai_emulation.info.is_primary_master);
if (oai_emulation.info.is_primary_master == 0) {
retry:
bypass_tx_data(WAIT_SM_TRANSPORT,0,0);
// just wait to recieve the master 0 msg
Master_list_rx = oai_emulation.info.master_list - 1;
if (bypass_rx_data(0,0,0,1) == -1) {
/* In case the master is not ready at time we send the first message */
sleep(1);
goto retry;
}
} else {
bypass_rx_data(0,0,0,0);
bypass_tx_data(WAIT_PM_TRANSPORT,0,0);
}
if (oai_emulation.info.master_list!=0) {
retry2:
bypass_tx_data(SYNC_TRANSPORT,0,0);
if (bypass_rx_data(0,0,0,0) == -1) {
goto retry2;
}
// i received the sync from all secondary masters
if (emu_rx_status == SYNCED_TRANSPORT) {
emu_tx_status = SYNCED_TRANSPORT;
}
LOG_D(EMU,"TX secondary master SYNC_TRANSPORT state \n");
}
LOG_D(EMU, "Leaving EMU transport SYNC is primary master %d\n",
oai_emulation.info.is_primary_master);
}
void emu_transport(unsigned int frame, unsigned int last_slot,
unsigned int next_slot,lte_subframe_t direction,
unsigned char frame_type,
int ethernet_flag )
{
if (ethernet_flag == 0) {
return;
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(
VCD_SIGNAL_DUMPER_FUNCTIONS_EMU_TRANSPORT, VCD_FUNCTION_IN);
if ((frame_type == 1) && (direction == SF_S)) {
if ((next_slot % 2) == 0) {
emu_transport_DL(frame, last_slot, next_slot);
} else {
emu_transport_UL(frame, last_slot , next_slot);
}
//DL
} else {
if ((next_slot % 2) == 0) {
if (((frame_type == 1) && (direction == SF_DL )) || (frame_type == 0) ) {
emu_transport_DL(frame, last_slot, next_slot);
}
}
// UL
if (((frame_type == 1) && (direction == SF_UL)) || (frame_type == 0) ) {
emu_transport_UL(frame, last_slot, next_slot);
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(
VCD_SIGNAL_DUMPER_FUNCTIONS_EMU_TRANSPORT, VCD_FUNCTION_OUT);
}
void emu_transport_DL(unsigned int frame, unsigned int last_slot,
unsigned int next_slot)
{
LOG_D(EMU, "Entering EMU transport DL, is primary master %d\n",
oai_emulation.info.is_primary_master);
if (oai_emulation.info.is_primary_master == 0) {
if (oai_emulation.info.nb_enb_local > 0) { // send in DL if
bypass_tx_data(ENB_TRANSPORT, frame, next_slot);
bypass_rx_data(frame, last_slot, next_slot, 1);
} else {
bypass_tx_data(WAIT_SM_TRANSPORT,frame,next_slot);
bypass_rx_data(frame, last_slot, next_slot, 0);
}
} else { // PM
if (oai_emulation.info.nb_enb_local>0) { // send in DL if
bypass_rx_data(frame, last_slot, next_slot, 1);
bypass_tx_data(ENB_TRANSPORT, frame, next_slot);
} else {
bypass_rx_data(frame, last_slot, next_slot, 0);
bypass_tx_data(WAIT_SM_TRANSPORT,frame,next_slot);
}
}
LOG_D(EMU, "Leaving EMU transport DL, is primary master %d\n",
oai_emulation.info.is_primary_master);
}
void emu_transport_UL(unsigned int frame, unsigned int last_slot,
unsigned int next_slot)
{
LOG_D(EMU, "Entering EMU transport UL, is primary master %d\n",
oai_emulation.info.is_primary_master);
if (oai_emulation.info.is_primary_master == 0) {
if (oai_emulation.info.nb_ue_local > 0) {
bypass_tx_data(UE_TRANSPORT, frame, next_slot);
bypass_rx_data(frame, last_slot, next_slot, 1);
} else {
bypass_tx_data(WAIT_SM_TRANSPORT, frame, next_slot);
bypass_rx_data(frame,last_slot, next_slot, 0);
}
} else {
if (oai_emulation.info.nb_ue_local > 0) {
bypass_rx_data(frame, last_slot, next_slot, 1);
bypass_tx_data(UE_TRANSPORT, frame, next_slot);
} else {
bypass_rx_data(frame,last_slot, next_slot, 0);
bypass_tx_data(WAIT_SM_TRANSPORT, frame, next_slot);
}
}
LOG_D(EMU, "Leaving EMU transport UL, is primary master %d\n",
oai_emulation.info.is_primary_master);
}
void emu_transport_release(void)
{
bypass_tx_data(RELEASE_TRANSPORT,0,0);
LOG_E(EMU," tx RELEASE_TRANSPORT \n");
}
unsigned int emul_tx_handler(unsigned char Mode,char *Tx_buffer,
unsigned int *Nbytes,unsigned int *Nb_flows)
{
return *Nbytes;
}
unsigned int emul_rx_data(void)
{
return(0);
}
unsigned int emul_rx_handler(unsigned char Mode,char *rx_buffer,
unsigned int Nbytes)
{
unsigned short Rx_size=0;
return (Rx_size+2);
}
void clear_eNB_transport_info(uint8_t nb_eNB)
{
uint8_t eNB_id;
uint8_t CC_id;
for (eNB_id=0; eNB_id<nb_eNB; eNB_id++) {
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
eNB_transport_info_TB_index[eNB_id][CC_id]=0;
memset((void *)&eNB_transport_info[eNB_id][CC_id].cntl,0,sizeof(eNB_cntl));
eNB_transport_info[eNB_id][CC_id].num_common_dci=0;
eNB_transport_info[eNB_id][CC_id].num_ue_spec_dci=0;
}
}
#ifdef DEBUG_EMU
LOG_D(EMU, "EMUL clear_eNB_transport_info\n");
#endif
}
void clear_UE_transport_info(uint8_t nb_UE)
{
uint8_t UE_id,CC_id;
for (UE_id=0; UE_id<nb_UE; UE_id++)
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
memset((void *)&UE_transport_info[UE_id][CC_id].cntl,0,sizeof(UE_cntl));
}
#ifdef DEBUG_EMU
LOG_D(EMU, "EMUL clear_UE_transport_info\n");
#endif
}
void fill_phy_enb_vars(unsigned int enb_id, uint8_t CC_id,unsigned int next_slot)
{
int n_dci = 0, n_dci_dl;
int payload_offset = 0;
unsigned int harq_pid;
LTE_eNB_DLSCH_t *dlsch_eNB;
unsigned short ue_id;
uint8_t nb_total_dci;
// eNB
// PBCH : copy payload
*(uint32_t *)RC.eNB[enb_id][CC_id]->pbch_pdu =
eNB_transport_info[enb_id][CC_id].cntl.pbch_payload;
/* LOG_I(EMU," RX slot %d ENB TRANSPORT pbch payload %d pdu[0] %d pdu[0] %d \n",
next_slot ,
eNB_transport_info[enb_id][CC_id].cntl.pbch_payload,
((uint8_t*)RC.eNB[enb_id]->pbch_pdu)[0],
((uint8_t*)RC.eNB[enb_id]->pbch_pdu)[1]);
*/
// }
//CFI
// not needed yet
//PHICH
// to be added later
//DCI
nb_total_dci= eNB_transport_info[enb_id][CC_id].num_pmch +
eNB_transport_info[enb_id][CC_id].num_ue_spec_dci +
eNB_transport_info[enb_id][CC_id].num_common_dci;
RC.eNB[enb_id][CC_id]->num_ue_spec_dci[(next_slot>>1)&1] =
eNB_transport_info[enb_id][CC_id].num_ue_spec_dci;
RC.eNB[enb_id][CC_id]->num_common_dci[(next_slot>>1)&1] =
eNB_transport_info[enb_id][CC_id].num_common_dci;
#ifdef DEBUG_EMU
LOG_D(EMU, "Fill phy vars eNB %d for slot %d, DCI found %d \n",
enb_id, next_slot, nb_total_dci);
#endif
if (nb_total_dci >0) {
memcpy(RC.eNB[enb_id][CC_id]->dci_alloc[(next_slot>>1)&1],
eNB_transport_info[enb_id][CC_id].dci_alloc,
(nb_total_dci) * sizeof(DCI_ALLOC_t));
n_dci_dl=0;
// fill dlsch_eNB structure from DCI
for (n_dci = 0; n_dci < nb_total_dci; n_dci++) {
//exclude ul dci
if ((eNB_transport_info[enb_id][CC_id].dci_alloc[n_dci_dl].format > 0) || (eNB_transport_info[enb_id][CC_id].num_pmch > 0 )) {
#ifdef DEBUG_EMU
LOG_D(EMU, "dci spec %d common %d pmch %d tbs is %d payload offset %d\n",
eNB_transport_info[enb_id][CC_id].num_ue_spec_dci,
eNB_transport_info[enb_id][CC_id].num_common_dci,
eNB_transport_info[enb_id][CC_id].num_pmch,
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl],
payload_offset);
#endif
switch (eNB_transport_info[enb_id][CC_id].dlsch_type[n_dci_dl]) {
case 0: //SI:
memcpy(RC.eNB[enb_id][CC_id]->dlsch_SI->harq_processes[0]->b,
&eNB_transport_info[enb_id][CC_id].transport_blocks[payload_offset],
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
#ifdef DEBUG_EMU
LOG_D(EMU, "SI eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]%d \n",
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
#endif
break;
case 1: //RA:
memcpy(RC.eNB[enb_id][CC_id]->dlsch_ra->harq_processes[0]->b,
&eNB_transport_info[enb_id][CC_id].transport_blocks[payload_offset],
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
#ifdef DEBUG_EMU
LOG_D(EMU, "RA eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]%d \n",
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
#endif
break;
case 2://TB0:
harq_pid = eNB_transport_info[enb_id][CC_id].harq_pid[n_dci_dl];
ue_id = eNB_transport_info[enb_id][CC_id].ue_id[n_dci_dl];
RC.eNB[enb_id][CC_id]->dlsch[ue_id][0]->rnti=
eNB_transport_info[enb_id][CC_id].dci_alloc[n_dci_dl].rnti;
dlsch_eNB = RC.eNB[enb_id][CC_id]->dlsch[ue_id][0];
#ifdef DEBUG_EMU
LOG_D(EMU,
" enb_id %d ue id is %d rnti is %x dci index %d, harq_pid %d tbs %d \n",
enb_id, ue_id, eNB_transport_info[enb_id][CC_id].dci_alloc[n_dci_dl].rnti,
n_dci_dl, harq_pid, eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
for (i=0; i<eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]; i++) {
LOG_T(EMU, "%x.",
(unsigned char) eNB_transport_info[enb_id][CC_id].transport_blocks[payload_offset+i]);
}
#endif
memcpy(dlsch_eNB->harq_processes[harq_pid]->b,
&eNB_transport_info[enb_id][CC_id].transport_blocks[payload_offset],
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
break;
case 3://TB1:
harq_pid = eNB_transport_info[enb_id][CC_id].harq_pid[n_dci_dl];
ue_id = eNB_transport_info[enb_id][CC_id].ue_id[n_dci_dl];
RC.eNB[enb_id][CC_id]->dlsch[ue_id][1]->rnti=
eNB_transport_info[enb_id][CC_id].dci_alloc[n_dci_dl].rnti;
dlsch_eNB = RC.eNB[enb_id][CC_id]->dlsch[ue_id][1];
memcpy(dlsch_eNB->harq_processes[harq_pid]->b,
&eNB_transport_info[enb_id][CC_id].transport_blocks[payload_offset],
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
break;
case 5:
memcpy(RC.eNB[enb_id][CC_id]->dlsch_MCH->harq_processes[0]->b,
&eNB_transport_info[enb_id][CC_id].transport_blocks[payload_offset],
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
#ifdef DEBUG_EMU
LOG_D(EMU, "PMCH eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl] %d \n",
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
#endif
break;
default:
LOG_W(EMU,"not supported dlsch type %d \n", eNB_transport_info[enb_id][CC_id].dlsch_type[n_dci_dl]);
break;
}
payload_offset += eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl];
}
n_dci_dl++;
}
#ifdef DEBUG_EMU
LOG_D(EMU, "Fill phy eNB vars done next slot %d !\n", next_slot);
#endif
}
}
void fill_phy_ue_vars(unsigned int ue_id, uint8_t CC_id,unsigned int last_slot)
{
int n_enb;//index
int enb_id;
// int harq_id;
// int payload_offset = 0;
unsigned short rnti;
unsigned int harq_pid;
LTE_UE_ULSCH_t *ulsch;
PUCCH_FMT_t pucch_format;
// uint8_t ue_transport_info_index[NUMBER_OF_eNB_MAX];
uint8_t subframe = (last_slot+1)>>1;
memcpy(&ue_cntl_delay[ue_id][CC_id][(last_slot+1)%2], &UE_transport_info[ue_id][CC_id].cntl,
sizeof(UE_cntl));
#ifdef DEBUG_EMU
LOG_D(EMU,
"Last slot %d subframe %d CC_id %d: Fill phy vars UE %d : PRACH is (%d,%d) preamble (%d,%d) SR (%d,%d), pucch_sel (%d, %d)\n",
last_slot,subframe,CC_id, ue_id,
UE_transport_info[ue_id][CC_id].cntl.prach_flag,
ue_cntl_delay[ue_id][CC_id][last_slot%2].prach_flag,
UE_transport_info[ue_id][CC_id].cntl.prach_id,
ue_cntl_delay[ue_id][CC_id][last_slot%2].prach_id,
UE_transport_info[ue_id][CC_id].cntl.sr,
ue_cntl_delay[ue_id][CC_id][last_slot%2].sr,
UE_transport_info[ue_id][CC_id].cntl.pucch_sel,
ue_cntl_delay[ue_id][CC_id][last_slot%2].pucch_sel);
#endif
//ue_cntl_delay[subframe%2].prach_flag ;
PHY_vars_UE_g[ue_id][CC_id]->generate_prach = ue_cntl_delay[ue_id][CC_id][last_slot%2].prach_flag;//UE_transport_info[ue_id][CC_id].cntl.prach_flag;
if (PHY_vars_UE_g[ue_id][CC_id]->generate_prach == 1) {
// if (PHY_vars_UE_g[ue_id][CC_id]->prach_resources[enb_id] == NULL)
// PHY_vars_UE_g[ue_id][CC_id]->prach_resources[enb_id] = malloc(sizeof(PRACH_RESOURCES_t));
//ue_cntl_delay[subframe%2].prach_id;
PHY_vars_UE_g[ue_id][CC_id]->prach_PreambleIndex =
ue_cntl_delay[ue_id][CC_id][last_slot%2].prach_id;
}
pucch_format= ue_cntl_delay[ue_id][CC_id][last_slot%2].pucch_flag;// UE_transport_info[ue_id][CC_id].cntl.pucch_flag;
if ((last_slot + 1) % 2 == 0) {
if (pucch_format == pucch_format1) { // UE_transport_info[ue_id][CC_id].cntl.sr;
PHY_vars_UE_g[ue_id][CC_id]->sr[subframe] = ue_cntl_delay[ue_id][CC_id][last_slot%2].sr;
} else if ((pucch_format == pucch_format1a) ||
(pucch_format == pucch_format1b)) {
PHY_vars_UE_g[ue_id][CC_id]->pucch_payload[0] = ue_cntl_delay[ue_id][CC_id][last_slot%2].pucch_payload;
//UE_transport_info[ue_id][CC_id].cntl.pucch_payload;
}
PHY_vars_UE_g[ue_id][CC_id]->pucch_sel[subframe] =
ue_cntl_delay[ue_id][CC_id][last_slot%2].pucch_sel;
}
#ifdef DEBUG_EMU
LOG_D(EMU,"subframe %d trying to copy the payload from num eNB %d to UE %d \n",
subframe, UE_transport_info[ue_id][CC_id].num_eNB, ue_id);
#endif
for (n_enb = 0; n_enb < UE_transport_info[ue_id][CC_id].num_eNB; n_enb++) {
rnti = UE_transport_info[ue_id][CC_id].rnti[n_enb];
enb_id = UE_transport_info[ue_id][CC_id].eNB_id[n_enb];
PHY_vars_UE_g[ue_id][CC_id]->pdcch_vars[0][enb_id]->crnti=rnti;
PHY_vars_UE_g[ue_id][CC_id]->pdcch_vars[1][enb_id]->crnti=rnti;
harq_pid = UE_transport_info[ue_id][CC_id].harq_pid[n_enb];
PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->o_RI[0] =
ue_cntl_delay[ue_id][CC_id][last_slot%2].pusch_ri & 0x1;
PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->o_RI[1] =
(ue_cntl_delay[ue_id][CC_id][last_slot%2].pusch_ri>>1) & 0x1;
PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->o_ACK[0]=
ue_cntl_delay[ue_id][CC_id][last_slot%2].pusch_ack & 0x1;
PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->o_ACK[1]=
(ue_cntl_delay[ue_id][CC_id][last_slot%2].pusch_ack>>1) & 0x1;
//*(uint32_t *)ulsch->o = ue_cntl_delay[ue_id][CC_id][last_slot%2].pusch_uci;
if ((last_slot % 2) == 1) {
PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->O =
ue_cntl_delay[ue_id][CC_id][last_slot%2].length_uci;
PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->uci_format =
ue_cntl_delay[ue_id][CC_id][last_slot%2].uci_format;
memcpy(PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->o,
ue_cntl_delay[ue_id][CC_id][last_slot%2].pusch_uci,
MAX_CQI_BYTES);
ulsch = PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id];
// if (((HLC_subband_cqi_rank1_2A_5MHz *)ulsch->o)->cqi1)
LOG_D(EMU,
"[UE %d] subframe %d last slot %d copy the payload from eNB %d to UE %d with harq id %d cqi (val %d, length %d) \n",
ue_id, subframe, last_slot, enb_id, ue_id, harq_pid,
((HLC_subband_cqi_rank1_2A_5MHz *)ulsch->o)->cqi1,
PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->O);
}
memcpy(PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->harq_processes[harq_pid]->b,
UE_transport_info[ue_id][CC_id].transport_blocks,
UE_transport_info[ue_id][CC_id].tbs[enb_id]);
//ue_transport_info_index[enb_id]+=UE_transport_info[ue_id][CC_id].tbs[enb_id];
//UE_transport_info[ue_id][CC_id].transport_blocks+=ue_transport_info_index[enb_id];
//LOG_T(EMU,"ulsch tbs is %d\n", UE_transport_info[ue_id][CC_id].tbs[enb_id]);
}
}

View File

@@ -1,329 +0,0 @@
/*
* 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
*/
/*! \file multicast_link.c
* \brief
* \author Lionel Gauthier and Navid Nikaein
* \date 2011
* \version 1.1
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/time.h>
#include <assert.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#define MULTICAST_LINK_C
#include "socket.h"
#include "multicast_link.h"
#include "common/utils/LOG/log.h"
extern unsigned short Master_id;
const char *multicast_group_list[MULTICAST_LINK_NUM_GROUPS] = {
"239.0.0.161",
"239.0.0.162",
"239.0.0.163",
"239.0.0.164"
};
static multicast_group_t group_list[MULTICAST_LINK_NUM_GROUPS];
/* Socket file descriptors we want to wake up for, using select() */
static fd_set socks;
/* Highest #'d file descriptor, needed for select() */
static int highsock;
#if ! defined(ENABLE_NEW_MULTICAST)
static pthread_t main_loop_thread;
#endif
static void (*rx_handler) (unsigned int, char *);
static unsigned char multicast_group;
static char *multicast_if;
//------------------------------------------------------------------------------
void
multicast_link_init(void)
{
//------------------------------------------------------------------------------
int group;
int multicast_loop;
int reuse_addr = 1;
static struct ip_mreq command;
struct sockaddr_in sin;
// struct ifreq ifr;
for (group = 0; group < MULTICAST_LINK_NUM_GROUPS; group++) {
//strcpy (group_list[group].host_addr, multicast_group_list[group]);
strncpy (group_list[group].host_addr, multicast_group_list[group], sizeof(group_list[group].host_addr));
group_list[group].host_addr[sizeof(group_list[group].host_addr) - 1] = 0; // terminate string
group_list[group].port = 46014 + group;
group_list[group].socket = make_socket_inet(
SOCK_DGRAM,
&group_list[group].port, &sin);
LOG_D(PHY, "multicast_link_init(): Created socket %d for group %d, port %d\n",
group_list[group].socket,group,group_list[group].port);
/* Used so we can re-bind to our port while a previous connection is still
* in TIME_WAIT state.
*/
if (setsockopt(group_list[group].socket, SOL_SOCKET, SO_REUSEADDR,
&reuse_addr, sizeof (reuse_addr)) < 0) {
LOG_E(PHY, "[MULTICAST] ERROR : setsockopt:SO_REUSEADDR, exiting ...");
exit (EXIT_FAILURE);
}
if (multicast_if != NULL) {
if (setsockopt(group_list[group].socket, SOL_SOCKET,SO_BINDTODEVICE,
multicast_if, strlen(multicast_if)) < 0) {
LOG_E(PHY,
"[MULTICAST] ERROR : setsockopt:SO_BINDTODEVICE on interface %s, exiting ...\n",
multicast_if);
LOG_E(PHY,
"[MULTICAST] make sure that you have a root privilage or run with sudo -E \n");
exit (EXIT_FAILURE);
}
}
#if !defined(ENABLE_NEW_MULTICAST)
/* Make the socket blocking */
socket_setnonblocking(group_list[group].socket);
#endif
multicast_loop = 0;
if (setsockopt (group_list[group].socket, IPPROTO_IP, IP_MULTICAST_LOOP,
&multicast_loop, sizeof (multicast_loop)) < 0) {
LOG_E(PHY,
"[MULTICAST] ERROR: %s line %d multicast_link_main_loop() IP_MULTICAST_LOOP %m",
__FILE__, __LINE__);
exit (EXIT_FAILURE);
}
// Join the broadcast group:
command.imr_multiaddr.s_addr = inet_addr (group_list[group].host_addr);
command.imr_interface.s_addr = htonl (INADDR_ANY);
if (command.imr_multiaddr.s_addr == -1) {
LOG_E(PHY, "[MULTICAST] ERROR: %s line %d NO MULTICAST", __FILE__, __LINE__);
exit (EXIT_FAILURE);
}
if (setsockopt (group_list[group].socket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
&command, sizeof (command)) < 0) {
LOG_E(PHY, "[MULTICAST] ERROR: %s line %d IP_ADD_MEMBERSHIP %m", __FILE__,
__LINE__);
exit (EXIT_FAILURE);
}
memset (&group_list[group].sock_remote_addr, 0, sizeof (struct sockaddr_in));
group_list[group].sock_remote_addr.sin_family = AF_INET;
group_list[group].sock_remote_addr.sin_addr.s_addr = inet_addr (multicast_group_list[group]);
group_list[group].sock_remote_addr.sin_port = htons (group_list[group].port);
}
}
//------------------------------------------------------------------------------
void
multicast_link_build_select_list (void)
{
//------------------------------------------------------------------------------
int group;
/* First put together fd_set for select(), which will
consist of the sock veriable in case a new connection
is coming in, plus all the sockets we have already
accepted. */
/* FD_ZERO() clears out the fd_set called socks, so that
it doesn't contain any file descriptors. */
FD_ZERO (&socks);
/* Loops through all the possible connections and adds
those sockets to the fd_set */
for (group = 0; group < MULTICAST_LINK_NUM_GROUPS; group++) {
if (group_list[group].socket != 0) {
FD_SET (group_list[group].socket, &socks);
if (group_list[group].socket > highsock) {
highsock = group_list[group].socket;
}
}
}
}
void
multicast_link_read_data (int groupP)
{
int num_bytes;
if ((groupP < MULTICAST_LINK_NUM_GROUPS) && (groupP >= 0)) {
if ((num_bytes = recvfrom (group_list[groupP].socket,
group_list[groupP].rx_buffer, 40000, 0, 0, 0)) < 0) {
LOG_E(PHY, "[MULTICAST] recvfrom has failed (%d:%s)\n (%s:%d)\n",
errno, strerror(errno), __FILE__, __LINE__);
} else {
rx_handler(num_bytes,group_list[groupP].rx_buffer);
}
} else {
LOG_E(PHY, "[MULTICAST] ERROR: groupP out of bounds %d\n", groupP);
}
}
//------------------------------------------------------------------------------
void
multicast_link_read (void)
{
//------------------------------------------------------------------------------
int group; /* Current item in connectlist for for loops */
/* Now check connectlist for available data */
/* Run through our sockets and check to see if anything
happened with them, if so 'service' them. */
for (group = multicast_group; group < MULTICAST_LINK_NUM_GROUPS ; group++) {
if (FD_ISSET (group_list[group].socket, &socks)) {
multicast_link_read_data (group);
break;
}
} /* for (all entries in queue) */
}
//------------------------------------------------------------------------------
int
multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP)
{
//------------------------------------------------------------------------------
int num;
if ((num = sendto (group_list[groupP].socket, dataP, sizeP, 0,
(struct sockaddr *) &group_list[groupP].sock_remote_addr,
sizeof (group_list[groupP].sock_remote_addr))) < 0) {
LOG_E(PHY, "[MULTICAST] sendto has failed (%d:%s)\n (%s:%d)\n",
errno, strerror(errno),
__FILE__, __LINE__);
}
return num;
}
int multicast_link_read_data_from_sock(uint8_t is_master)
{
struct timeval timeout, *timeout_p;
int readsocks; /* Number of sockets ready for reading */
timeout.tv_sec = 0;
timeout.tv_usec = 15000;
if (is_master == 0) {
/* UE will block indefinetely if no data is sent from eNB
* NOTE: a NULL timeout for select will block indefinetely
*/
timeout_p = NULL;
} else {
/* In case of eNB set the timeout to 500 usecs after which we consider
* the packets as dropped.
*/
timeout_p = &timeout;
}
highsock = -1;
multicast_link_build_select_list ();
LOG_D(PHY, "Stuck on select with timeout %s\n",
timeout_p == NULL ? "infinite" : "15000 usecs");
readsocks = select(highsock + 1, &socks, (fd_set *) 0, (fd_set *) 0, timeout_p);
if (readsocks < 0) {
LOG_E(PHY, "Multicast select failed (%d:%s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
} else if (readsocks > 0) {
multicast_link_read();
} else {
/* Timeout */
LOG_I(PHY, "Multicast select time-out\n");
return 1;
}
return 0;
}
void* multicast_link_main_loop (void *param)
{
while (1) {
multicast_link_read_data_from_sock(0);
}
return NULL;
}
void multicast_link_start(void (*rx_handlerP) (unsigned int, char *),
unsigned char _multicast_group, char *multicast_ifname)
{
rx_handler = rx_handlerP;
multicast_group = _multicast_group;
multicast_if = multicast_ifname;
LOG_I(PHY, "[MULTICAST] LINK START on interface=%s for group=%d: handler=%p\n",
(multicast_if == NULL) ? "not specified" : multicast_if, multicast_group,
rx_handler);
multicast_link_init ();
#if ! defined(ENABLE_NEW_MULTICAST)
LOG_D(PHY, "[MULTICAST] multicast link start thread\n");
if (pthread_create (&main_loop_thread, NULL, multicast_link_main_loop,
NULL) != 0) {
LOG_E(PHY, "[MULTICAST LINK] Error in pthread_create (%d:%s)\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
} else {
pthread_detach(main_loop_thread); // disassociate from parent
LOG_I(PHY, "[MULTICAST LINK] Thread detached\n");
}
#endif
}

View File

@@ -1,66 +0,0 @@
/*
* 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
*/
/*! \file multicast_link.h
* \brief
* \author Lionel Gauthier and Navid Nikaein
* \date 2011
* \version 1.1
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
*/
#ifndef __MULTICAST_LINK_H__
# define __MULTICAST_LINK_H__
# ifdef MULTICAST_LINK_C
# define private_multicast_link(x) x
# define public_multicast_link(x) x
# else
# define private_multicast_link(x)
# define public_multicast_link(x) extern x
# endif
# include "stdint.h"
private_multicast_link (typedef struct multicast_group_t {
int socket;
struct sockaddr_in sock_remote_addr;
char host_addr[16];
uint16_t port;
char rx_buffer[40000];
} multicast_group_t;)
#define MULTICAST_LINK_NUM_GROUPS 4
extern const char *multicast_group_list[MULTICAST_LINK_NUM_GROUPS];
private_multicast_link(void multicast_link_init (void));
private_multicast_link(void multicast_link_read_data (int groupP));
private_multicast_link(void multicast_link_read (void));
private_multicast_link(void *multicast_link_main_loop (void *param));
public_multicast_link(int multicast_link_write_sock (int groupP, char *dataP, uint32_t sizeP));
public_multicast_link(void multicast_link_start ( void (*rx_handlerP) (unsigned int, char*), unsigned char multicast_group, char * multicast_ifname));
# ifdef BYPASS_PHY
public_multicast_link(pthread_mutex_t Bypass_phy_wr_mutex);
public_multicast_link(pthread_cond_t Bypass_phy_wr_cond);
public_multicast_link(char Bypass_phy_wr);
# endif //BYPASS_PHY
#endif

View File

@@ -51,10 +51,6 @@
char nl_rx_buf[NL_MAX_PAYLOAD];
struct sockaddr_nl nas_src_addr, nas_dest_addr;
struct nlmsghdr *nas_nlh_tx = NULL;
struct nlmsghdr *nas_nlh_rx = NULL;
struct iovec nas_iov_tx;
struct iovec nas_iov_rx = {nl_rx_buf, sizeof(nl_rx_buf)};
int nas_sock_fd[MAX_MOBILES_PER_ENB*2]; //Allocated for both LTE UE and NR UE.
@@ -63,8 +59,6 @@ int nas_sock_mbms_fd;
struct msghdr nas_msg_tx;
struct msghdr nas_msg_rx;
#define GRAAL_NETLINK_ID 31
static int tun_alloc(char *dev) {
struct ifreq ifr;
int fd, err;
@@ -99,17 +93,12 @@ int netlink_init_mbms_tun(char *ifprefix, int id) {//for UE, id = 1, 2, ...,
int ret;
char ifname[64];
if (id > 0) {
sprintf(ifname, "oaitun_%.3s%d", ifprefix, id-1);
}
else {
sprintf(ifname, "oaitun_%.3s1", ifprefix); // added "1": for historical reasons
}
nas_sock_mbms_fd = tun_alloc(ifname);
sprintf(ifname, "%s%d", ifprefix, id);
nas_sock_mbms_fd = tun_alloc(ifname);
if (nas_sock_mbms_fd == -1) {
printf("[NETLINK] Error opening mbms socket %s (%d:%s)\n",ifname,errno, strerror(errno));
exit(1);
if (nas_sock_mbms_fd == -1) {
printf("[NETLINK] Error opening mbms socket %s (%d:%s)\n", ifname, errno, strerror(errno));
exit(1);
}
printf("[NETLINK]Opened socket %s with fd %d\n",ifname,nas_sock_mbms_fd);
@@ -132,14 +121,15 @@ int netlink_init_mbms_tun(char *ifprefix, int id) {//for UE, id = 1, 2, ...,
return 1;
}
int netlink_init_tun(char *ifprefix, int num_if, int id) {//for UE, id = 1, 2, ...,
int netlink_init_tun(const char *ifprefix, int num_if, int id)
{
int ret;
char ifname[64];
int begx = (id == 0) ? 0 : id - 1;
int endx = (id == 0) ? num_if : id;
for (int i = begx; i < endx; i++) {
sprintf(ifname, "oaitun_%.3s%d",ifprefix,i+1);
sprintf(ifname, "%s%d",ifprefix,i+1);
nas_sock_fd[i] = tun_alloc(ifname);
if (nas_sock_fd[i] == -1) {
@@ -162,66 +152,3 @@ int netlink_init_tun(char *ifprefix, int num_if, int id) {//for UE, id = 1, 2, .
return 1;
}
int netlink_init(void) {
int ret;
nas_sock_fd[0] = socket(PF_NETLINK, SOCK_RAW,GRAAL_NETLINK_ID);
if (nas_sock_fd[0] == -1) {
printf("[NETLINK] Error opening GRAAL_NETLINK_ID socket %d (%d:%s)\n",nas_sock_fd[0],errno, strerror(errno));
if (LINK_ENB_PDCP_TO_IP_DRIVER) {
exit(1);
}
}
printf("[NETLINK] Opened socket with fd %d\n",nas_sock_fd[0]);
ret = fcntl(nas_sock_fd[0],F_SETFL,O_NONBLOCK);
if (ret == -1) {
printf("[NETLINK] Error fcntl (%d:%s)\n",errno, strerror(errno));
if (LINK_ENB_PDCP_TO_IP_DRIVER) {
exit(1);
}
}
memset(&nas_src_addr, 0, sizeof(nas_src_addr));
nas_src_addr.nl_family = AF_NETLINK;
nas_src_addr.nl_pid = 1;//getpid(); /* self pid */
nas_src_addr.nl_groups = 0; /* not in mcast groups */
ret = bind(nas_sock_fd[0], (struct sockaddr *)&nas_src_addr, sizeof(nas_src_addr));
memset(&nas_dest_addr, 0, sizeof(nas_dest_addr));
nas_dest_addr.nl_family = AF_NETLINK;
nas_dest_addr.nl_pid = 0; /* For Linux Kernel */
nas_dest_addr.nl_groups = 0; /* unicast */
// TX PART
free(nas_nlh_tx);
nas_nlh_tx=(struct nlmsghdr *)malloc(NLMSG_SPACE(NL_MAX_PAYLOAD));
memset(nas_nlh_tx, 0, NLMSG_SPACE(NL_MAX_PAYLOAD));
/* Fill the netlink message header */
nas_nlh_tx->nlmsg_len = NLMSG_SPACE(NL_MAX_PAYLOAD);
nas_nlh_tx->nlmsg_pid = 1;//getpid(); /* self pid */
nas_nlh_tx->nlmsg_flags = 0;
nas_iov_tx.iov_base = (void *)nas_nlh_tx;
nas_iov_tx.iov_len = nas_nlh_tx->nlmsg_len;
memset(&nas_msg_tx,0,sizeof(nas_msg_tx));
nas_msg_tx.msg_name = (void *)&nas_dest_addr;
nas_msg_tx.msg_namelen = sizeof(nas_dest_addr);
nas_msg_tx.msg_iov = &nas_iov_tx;
nas_msg_tx.msg_iovlen = 1;
// RX PART
memset(&nas_msg_rx,0,sizeof(nas_msg_rx));
nas_msg_rx.msg_name = (void *)&nas_src_addr;
nas_msg_rx.msg_namelen = sizeof(nas_src_addr);
nas_msg_rx.msg_iov = &nas_iov_rx;
nas_msg_rx.msg_iovlen = 1;
return(nas_sock_fd[0]);
}
void netlink_cleanup(void)
{
free(nas_nlh_tx);
nas_nlh_tx = NULL;
}

View File

@@ -28,42 +28,10 @@
* \email: navid.nikaein@eurecom.fr
*/
#include "SIMULATION/ETH_TRANSPORT/defs.h"
#ifndef EMU_PROTO_H_
#define EMU_PROTO_H_
void init_bypass (void);
void bypass_init ( unsigned int (*tx_handlerP) (unsigned char,char *, unsigned int *, unsigned int *),unsigned int (*rx_handlerP) (unsigned char,char *,unsigned int));
int bypass_rx_data(unsigned int frame, unsigned int last_slot,
unsigned int next_slot, uint8_t is_master);
void bypass_signal_mac_phy(unsigned int frame, unsigned int last_slot,
unsigned int next_slot, uint8_t is_master);
void bypass_tx_data (emu_transport_info_t Type, unsigned int frame, unsigned int next_slot);
void emulation_tx_rx(void);
unsigned int emul_tx_handler(unsigned char Mode,char *Tx_buffer,unsigned int *Nbytes,unsigned int *Nb_flows);
unsigned int emul_rx_handler(unsigned char Mode,char *rx_buffer, unsigned int Nbytes);
unsigned int emul_rx_data(void);
void emu_transport_info(unsigned int last_slot, unsigned int next_slot);
void fill_phy_enb_vars(unsigned int enb_id, uint8_t CC_id,unsigned int next_slot);
void fill_phy_ue_vars(unsigned int ue_id, uint8_t CC_id,unsigned int last_slot);
void emu_transport_sync(void);
void emu_transport(unsigned int frame, unsigned int last_slot,unsigned int next_slot, lte_subframe_t direction, unsigned char frame_type, int ethernet_flag );
void emu_transport_DL(unsigned int frame, unsigned int last_slot,unsigned int next_slot);
void emu_transport_UL(unsigned int frame, unsigned int last_slot,unsigned int next_slot);
void emu_transport_release(void);
int multicast_link_read_data_from_sock(uint8_t eNB_flag);
void clear_eNB_transport_info(uint8_t);
void clear_UE_transport_info(uint8_t);
int netlink_init(void);
int netlink_init_tun(char *ifsuffix, int num_if, int id);
int netlink_init_tun(const char *ifprefix, int num_if, int id);
int netlink_init_mbms_tun(char *ifsuffix, int id);
void netlink_cleanup(void);
#endif /* EMU_PROTO_H_ */

View File

@@ -1,109 +0,0 @@
/*
* 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
*/
/*! \file socket.c
* \brief
* \author Lionel Gauthier
* \date 2011
* \version 1.0
* \company Eurecom
* \email: lionel.gauthier@eurecom.fr
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
//#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <assert.h>
#define SOCKET_C
//#include "openair_defs.h"
#include "socket.h"
#define msg printf
//------------------------------------------------------------------------------
void
socket_setnonblocking (int sockP)
{
//------------------------------------------------------------------------------
int opts;
opts = fcntl (sockP, F_GETFL);
if (opts < 0) {
perror ("fcntl(F_GETFL)");
exit (EXIT_FAILURE);
}
opts = (opts | O_NONBLOCK);
if (fcntl (sockP, F_SETFL, opts) < 0) {
perror ("fcntl(F_SETFL)");
exit (EXIT_FAILURE);
}
return;
}
//------------------------------------------------------------------------------
int
make_socket_inet (int typeP, uint16_t * portP, struct sockaddr_in *ptr_addressP)
{
//------------------------------------------------------------------------------
int sock;
unsigned int length = sizeof (struct sockaddr_in);
struct sockaddr_in name;
assert ((typeP == SOCK_STREAM) || (typeP == SOCK_DGRAM));
/* Create the socket. */
sock = socket (PF_INET, typeP, 0);
if (sock < 0) {
fprintf (stderr, "ERROR: %s line %d socket %m", __FILE__, __LINE__);
exit (EXIT_FAILURE);
}
/* Give the socket a name. */
name.sin_family = AF_INET;
name.sin_port = htons (*portP);
name.sin_addr.s_addr = htonl (INADDR_ANY);
if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
close (sock);
fprintf (stderr, "ERROR: %s line %d bind port %d %m", __FILE__, __LINE__, *portP);
exit (EXIT_FAILURE);
}
if (ptr_addressP != NULL) {
getsockname (sock, (struct sockaddr *) ptr_addressP, &length);
}
msg("[SOCKET] bound socket port %d\n", *portP);
return sock;
}

View File

@@ -1,46 +0,0 @@
/*
* 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
*/
/*! \file socket.h
* \brief
* \author Lionel Gauthier
* \date 2011
* \version 1.0
* \company Eurecom
* \email: lionel.gauthier@eurecom.fr
*/
#ifndef __SIMULATION_ETH_TRANSPORT_SOCKET__H__
#define __SIMULATION_ETH_TRANSPORT_SOCKET__H__
# ifdef SOCKET_C
# define private_socket(x) x
# define public_socket(x) x
# else
# define private_socket(x)
# define public_socket(x) extern x
# endif
# include "stdint.h"
public_socket (void socket_setnonblocking (int sockP);
)
public_socket (int make_socket_inet (int typeP, uint16_t * portP, struct sockaddr_in *ptr_addressP);
)
#endif

View File

@@ -47,8 +47,6 @@ SLDCH_t *ue_get_sldch(module_id_t module_idP, int CC_id,frame_t frameP, sub_fram
SLSCH_t *ue_get_slsch(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t subframe) {return(NULL);}
void multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP) {}
uint16_t
ue_process_rar(const module_id_t module_idP,
const int CC_id,

View File

@@ -279,14 +279,13 @@ int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id
uint8_t *mb = malloc16(ie->value.choice.RRCContainer.size);
memcpy(mb, ie->value.choice.RRCContainer.buf, ie->value.choice.RRCContainer.size);
LOG_D(F1AP, "Calling pdcp_data_ind for UE RNTI %lx srb_id %lu with size %ld (DCCH) \n", ctxt.rntiMaybeUEid, srb_id, ie->value.choice.RRCContainer.size);
//for (int i = 0; i < ie->value.choice.RRCContainer.size; i++)
// printf("%02x ", mb->data[i]);
//printf("\n");
pdcp_data_ind (&ctxt,
1, // srb_flag
0, // embms_flag
srb_id,
ie->value.choice.RRCContainer.size,
mb, NULL, NULL);
nr_pdcp_data_ind(&ctxt,
1, // srb_flag
0, // embms_flag
srb_id,
ie->value.choice.RRCContainer.size,
mb,
NULL,
NULL);
return 0;
}

View File

@@ -113,7 +113,7 @@ struct sockaddr_in prose_ctrl_addr;
struct sockaddr_in prose_pdcp_addr;
struct sockaddr_in pdcp_sin;
/* pdcp module parameters and related functions*/
static pdcp_params_t pdcp_params= {0,NULL};
static pdcp_params_t pdcp_params = {0};
rnti_t pdcp_UE_UE_module_id_to_rnti[MAX_MOBILES_PER_ENB];
rnti_t pdcp_eNB_UE_instance_to_rnti[MAX_MOBILES_PER_ENB]; // for noS1 mode
unsigned int pdcp_eNB_UE_instance_to_rnti_index;
@@ -298,8 +298,8 @@ bool pdcp_data_req(protocol_ctxt_t *ctxt_pP,
LOG_UI(PDCP, "Before rlc_data_req 1, srb_flagP: %d, rb_idP: %ld \n", srb_flagP, rb_idP);
}
rlc_status = pdcp_params.send_rlc_data_req_func(ctxt_pP, srb_flagP, MBMS_FLAG_YES, rb_idP, muiP,
confirmP, sdu_buffer_sizeP, pdcp_pdu_p,NULL,NULL);
rlc_status =
rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_YES, rb_idP, muiP, confirmP, sdu_buffer_sizeP, pdcp_pdu_p, NULL, NULL);
} else {
rlc_status = RLC_OP_STATUS_OUT_OF_RESSOURCES;
LOG_E(PDCP,PROTOCOL_CTXT_FMT" PDCP_DATA_REQ SDU DROPPED, OUT OF MEMORY \n",
@@ -467,9 +467,16 @@ bool pdcp_data_req(protocol_ctxt_t *ctxt_pP,
if ((pdcp_pdu_p!=NULL) && (srb_flagP == 0) && (ctxt_pP->enb_flag == 1)) {
LOG_D(PDCP, "pdcp data req on drb %ld, size %d, rnti %lx\n", rb_idP, pdcp_pdu_size, ctxt_pP->rntiMaybeUEid);
rlc_status = pdcp_params.send_rlc_data_req_func(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP,
confirmP, pdcp_pdu_size, pdcp_pdu_p,sourceL2Id,
destinationL2Id);
rlc_status = rlc_data_req(ctxt_pP,
srb_flagP,
MBMS_FLAG_NO,
rb_idP,
muiP,
confirmP,
pdcp_pdu_size,
pdcp_pdu_p,
sourceL2Id,
destinationL2Id);
ret = false;
switch (rlc_status) {
case RLC_OP_STATUS_OK:
@@ -2279,63 +2286,34 @@ void rrc_pdcp_config_req (
}
}
pdcp_data_ind_func_t get_pdcp_data_ind_func() {
return pdcp_params.pdcp_data_ind_func;
}
void pdcp_set_rlc_data_req_func(send_rlc_data_req_func_t send_rlc_data_req) {
pdcp_params.send_rlc_data_req_func = send_rlc_data_req;
}
void pdcp_set_pdcp_data_ind_func(pdcp_data_ind_func_t pdcp_data_ind) {
pdcp_params.pdcp_data_ind_func = pdcp_data_ind;
}
uint64_t pdcp_module_init( uint64_t pdcp_optmask, int id) {
/* temporary enforce netlink when UE_NAS_USE_TUN is set,
this is while switching from noS1 as build option
to noS1 as config option */
if ( pdcp_optmask & UE_NAS_USE_TUN_BIT) {
pdcp_params.optmask = pdcp_params.optmask | PDCP_USE_NETLINK_BIT ;
pdcp_params.optmask = pdcp_params.optmask;
}
pdcp_params.optmask = pdcp_params.optmask | pdcp_optmask ;
LOG_I(PDCP, "pdcp init,%s %s\n",
((LINK_ENB_PDCP_TO_GTPV1U)?"usegtp":""),
((PDCP_USE_NETLINK)?"usenetlink":""));
if (PDCP_USE_NETLINK) {
nas_getparams();
if(UE_NAS_USE_TUN) {
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF)? MAX_MOBILES_PER_ENB : 1;
netlink_init_tun("ue",num_if, id);
if (IS_SOFTMODEM_NOS1)
nas_config(1, 1, 2, "ue");
netlink_init_mbms_tun("uem", id);
nas_config_mbms(1, 2, 2, "uem");
LOG_I(PDCP, "UE pdcp will use tun interface\n");
} else if(ENB_NAS_USE_TUN) {
netlink_init_tun("enb", 1, 0);
nas_config(1, 1, 1, "enb");
if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){
netlink_init_mbms_tun("enm", 0);
nas_config_mbms(1, 2, 1, "enm");
LOG_I(PDCP, "ENB pdcp will use mbms tun interface\n");
}
LOG_I(PDCP, "ENB pdcp will use tun interface\n");
} else {
LOG_I(PDCP, "pdcp will use kernel modules\n");
netlink_init();
if(UE_NAS_USE_TUN) {
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF)? MAX_MOBILES_PER_ENB : 1;
netlink_init_tun("oaitun_ue",num_if, id);
if (IS_SOFTMODEM_NOS1)
nas_config(1, AF_INET, "10.0.1.2", "oaitun_ue");
netlink_init_mbms_tun("oaitun_uem", id + 1);
nas_config(1, AF_INET, "10.0.2.2", "oaitun_uem");
LOG_I(PDCP, "UE pdcp will use tun interface\n");
} else if(ENB_NAS_USE_TUN) {
netlink_init_tun("oaitun_enb", 1, 0);
nas_config(1, AF_INET, "10.0.1.1", "oaitun_enb");
if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){
netlink_init_mbms_tun("oaitun_enm", 1);
nas_config(1, AF_INET, "10.0.2.1", "oaitun_enm");
LOG_I(PDCP, "ENB pdcp will use mbms tun interface\n");
}
}else{
if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){
LOG_W(PDCP, "ENB pdcp will use tun interface for MBMS\n");
netlink_init_mbms_tun("enm", 0);
nas_config_mbms_s1(1, 2, 1, "enm");
}else
LOG_E(PDCP, "ENB pdcp will not use tun interface\n");
}
LOG_I(PDCP, "ENB pdcp will use tun interface\n");
}
pthread_create(&pdcp_stats_thread_desc,NULL,pdcp_stats_thread,NULL);
@@ -2362,7 +2340,6 @@ pdcp_free (
void pdcp_module_cleanup (void)
//-----------------------------------------------------------------------------
{
netlink_cleanup();
}
//-----------------------------------------------------------------------------

View File

@@ -47,42 +47,17 @@
#include "openair3/SECU/secu_defs.h"
typedef rlc_op_status_t (*send_rlc_data_req_func_t)(const protocol_ctxt_t *const,
const srb_flag_t,
const MBMS_flag_t,
const rb_id_t,
const mui_t,
confirm_t,
sdu_size_t,
uint8_t *,
const uint32_t *const,
const uint32_t *const);
typedef bool(pdcp_data_ind_t)(const protocol_ctxt_t *,
const srb_flag_t,
const MBMS_flag_t,
const rb_id_t,
const sdu_size_t,
uint8_t *,
const uint32_t *const,
const uint32_t *const);
typedef pdcp_data_ind_t* pdcp_data_ind_func_t;
#define MAX_NUMBER_NETIF 1 //16
#define ENB_NAS_USE_TUN_W_MBMS_BIT (1<< 10)
#define PDCP_USE_NETLINK_BIT (1<< 11)
#define LINK_ENB_PDCP_TO_IP_DRIVER_BIT (1<< 13)
#define LINK_ENB_PDCP_TO_GTPV1U_BIT (1<< 14)
#define UE_NAS_USE_TUN_BIT (1<< 15)
#define ENB_NAS_USE_TUN_BIT (1<< 16)
typedef struct {
uint64_t optmask;
send_rlc_data_req_func_t send_rlc_data_req_func;
pdcp_data_ind_func_t pdcp_data_ind_func;
} pdcp_params_t;
#define PDCP_USE_NETLINK ( get_pdcp_optmask() & PDCP_USE_NETLINK_BIT)
#define LINK_ENB_PDCP_TO_IP_DRIVER ( get_pdcp_optmask() & LINK_ENB_PDCP_TO_IP_DRIVER_BIT)
#define LINK_ENB_PDCP_TO_GTPV1U ( get_pdcp_optmask() & LINK_ENB_PDCP_TO_GTPV1U_BIT)
#define UE_NAS_USE_TUN ( get_pdcp_optmask() & UE_NAS_USE_TUN_BIT)
@@ -279,7 +254,7 @@ bool cu_f1u_data_req(protocol_ctxt_t *ctxt_pP,
const uint32_t *const sourceL2Id,
const uint32_t *const destinationL2Id);
/*! \fn bool pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, uint8_t*, bool)
/*! \fn bool pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, uint8_t*, uint32_t, uint32_t)
* \brief This functions handles data transfer indications coming from RLC
* \param[in] ctxt_pP Running context.
* \param[in] Shows if rb is SRB
@@ -287,12 +262,20 @@ bool cu_f1u_data_req(protocol_ctxt_t *ctxt_pP,
* \param[in] rab_id Radio Bearer ID
* \param[in] sdu_buffer_size Size of incoming SDU in bytes
* \param[in] sdu_buffer Buffer carrying SDU
* \param[in] is_data_plane flag to indicate whether the userplane data belong to the control plane or data plane
* \param[in] srcID
* \param[in] dstID
* \return TRUE on success, false otherwise
* \note None
* @ingroup _pdcp
*/
pdcp_data_ind_t pdcp_data_ind;
bool pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
const rb_id_t rb_idP,
const sdu_size_t sdu_buffer_sizeP,
uint8_t *const sdu_buffer_pP,
const uint32_t *const srcID,
const uint32_t *const dstID);
/*! \fn void rrc_pdcp_config_req(const protocol_ctxt_t* const ,uint32_t,rb_id_t,uint8_t)
* \brief This functions initializes relevant PDCP entity
@@ -381,9 +364,6 @@ int pdcp_fifo_flush_sdus ( const protocol_ctxt_t *const ct
int pdcp_fifo_read_input_sdus_remaining_bytes ( const protocol_ctxt_t *const ctxt_pP);
int pdcp_fifo_read_input_sdus ( const protocol_ctxt_t *const ctxt_pP);
void pdcp_fifo_read_input_sdus_from_otg ( const protocol_ctxt_t *const ctxt_pP);
void pdcp_set_rlc_data_req_func(send_rlc_data_req_func_t send_rlc_data_req);
void pdcp_set_pdcp_data_ind_func(pdcp_data_ind_func_t pdcp_data_ind);
pdcp_data_ind_func_t get_pdcp_data_ind_func(void);
//-----------------------------------------------------------------------------
int pdcp_fifo_flush_mbms_sdus ( const protocol_ctxt_t *const ctxt_pP);
int pdcp_fifo_read_input_mbms_sdus_fromtun ( const protocol_ctxt_t *const ctxt_pP);

View File

@@ -49,7 +49,6 @@ extern int otg_enabled;
#include "../MAC/mac_extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "NETWORK_DRIVER/LITE/constant.h"
//#include "SIMULATION/ETH_TRANSPORT/extern.h"
#include "common/utils/LOG/log.h"
#include "UTIL/OTG/otg_tx.h"
@@ -63,7 +62,6 @@ extern int otg_enabled;
#include <sys/socket.h>
#include <linux/netlink.h>
#include "NETWORK_DRIVER/UE_IP/constant.h"
extern char nl_rx_buf[NL_MAX_PAYLOAD];
extern struct sockaddr_nl nas_src_addr, nas_dest_addr;
@@ -136,12 +134,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
log_dump(PDCP, pdcpData, pdcpHead->data_size, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n");
ret = write(nas_sock_fd[0], pdcpData, pdcpHead->data_size);
LOG_T(PDCP,"[NB PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[0],pdcpHead->data_size);
} else if (PDCP_USE_NETLINK) {
int sizeToWrite= sizeof (pdcp_data_ind_header_t) + pdcpHead->data_size;
memcpy(NLMSG_DATA(nas_nlh_tx), (uint8_t *) pdcpHead, sizeToWrite);
nas_nlh_tx->nlmsg_len = sizeToWrite;
ret = sendmsg(nas_sock_fd[0],&nas_msg_tx,0);
} // PDCP_USE_NETLINK
}
AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s), nas_sock_fd[0]: %d\n", errno, strerror(errno), nas_sock_fd[0]);
@@ -422,9 +415,9 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 );
if (len > 0) {
for (nas_nlh_rx = (struct nlmsghdr *) nl_rx_buf;
NLMSG_OK (nas_nlh_rx, len);
nas_nlh_rx = NLMSG_NEXT (nas_nlh_rx, len)) {
for (struct nlmsghdr *nas_nlh_rx = (struct nlmsghdr *)nl_rx_buf;
NLMSG_OK(nas_nlh_rx, len);
nas_nlh_rx = NLMSG_NEXT(nas_nlh_rx, len)) {
if (nas_nlh_rx->nlmsg_type == NLMSG_DONE) {
LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_DONE\n");
//return;
@@ -526,7 +519,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx
ctxt.rntiMaybeUEid = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id];
if (rab_id != 0) {
if (rab_id == UE_IP_DEFAULT_RAB_ID) {
if (rab_id == 1) {
LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%lx, enb_flag=%d)\n", ctxt.module_id, ctxt.rntiMaybeUEid, ctxt.enb_flag);
key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rntiMaybeUEid, ctxt.enb_flag);
h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
@@ -700,7 +693,7 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP)
//UE
if (!ctxt.enb_flag) {
if (rab_id != 0) {
if (rab_id == UE_IP_DEFAULT_RAB_ID) {
if (rab_id == 1) {
LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%lx, enb_flag=%d)\n", ctxt.module_id, ctxt.rntiMaybeUEid, ctxt.enb_flag);
key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rntiMaybeUEid, ctxt.enb_flag);
h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
@@ -807,15 +800,10 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP)
} /* pdcp_fifo_read_input_sdus_frompc5s */
//-----------------------------------------------------------------------------
int pdcp_fifo_read_input_sdus (const protocol_ctxt_t *const ctxt_pP) {
if (UE_NAS_USE_TUN || ENB_NAS_USE_TUN) {
return pdcp_fifo_read_input_sdus_fromtun (ctxt_pP);
} else if (PDCP_USE_NETLINK) {
pdcp_fifo_read_input_sdus_frompc5s (ctxt_pP);
return pdcp_fifo_read_input_sdus_fromnetlinksock(ctxt_pP);
} /* PDCP_USE_NETLINK */
return 0;
int pdcp_fifo_read_input_sdus(const protocol_ctxt_t *const ctxt_pP)
{
DevAssert(UE_NAS_USE_TUN || ENB_NAS_USE_TUN);
return pdcp_fifo_read_input_sdus_fromtun(ctxt_pP);
}
//TTN for D2D (PC5S)

View File

@@ -1,269 +0,0 @@
/*
* 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
*/
/*! \file pdcp_netlink.c
* \brief pdcp communication with linux IP interface,
* have a look at http://man7.org/linux/man-pages/man7/netlink.7.html for netlink.
* Read operation from netlink should be achieved in an asynchronous way to avoid
* subframe overload, netlink congestion...
* \author Sebastien ROUX
* \date 2013
* \version 0.1
* @ingroup pdcp
*/
#define _GNU_SOURCE // required for pthread_setname_np()
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <error.h>
#include <unistd.h>
/* Bugfix for version of GCC = 4.4.3 (Ubuntu 10.04) */
#if GCC_VERSION <= 40403
#include <sys/socket.h>
#endif
#include <linux/netlink.h>
#include "assertions.h"
#include "queue.h"
#include "liblfds611.h"
#include "common/utils/LOG/log.h"
#include "common/utils/system.h"
#include "LAYER2/MAC/mac_extern.h"
#include "pdcp.h"
#include "pdcp_primitives.h"
#define PDCP_QUEUE_NB_ELEMENTS 200
extern char nl_rx_buf[NL_MAX_PAYLOAD];
extern struct nlmsghdr *nas_nlh_rx;
extern struct iovec nas_iov_rx;
extern int nas_sock_fd;
extern struct msghdr nas_msg_rx;
static pthread_t pdcp_netlink_thread;
/* We use lock-free queues between the User-plane driver running in kernel-space
* and the corresponding entity in User-space.
* one queue for eNBs (index 0)/one queue for UEs (index 1)
*/
static struct lfds611_queue_state **pdcp_netlink_queue_enb = NULL;
static struct lfds611_queue_state **pdcp_netlink_queue_ue = NULL;
static uint32_t *pdcp_netlink_nb_element_enb = NULL;
static uint32_t *pdcp_netlink_nb_element_ue = NULL;
time_stats_t ip_pdcp_stats_tmp;
static void *pdcp_netlink_thread_fct(void *arg);
//-----------------------------------------------------------------------------
int
pdcp_netlink_init(
void
)
//-----------------------------------------------------------------------------
{
int i;
int nb_inst_enb;
int nb_inst_ue;
reset_meas(&ip_pdcp_stats_tmp);
nb_inst_enb = 1;
nb_inst_ue = 1;
if (LINK_ENB_PDCP_TO_GTPV1U) {
nb_inst_enb = 0;
LOG_I(PDCP, "[NETLINK] Creating 0 queues for eNB Netlink -> PDCP communication\n");
} else {
/* #warning " LG: When there will be handover in, there will problems because dim is based on local nums of ues" */
pdcp_netlink_queue_enb = calloc(nb_inst_enb, sizeof(struct lfds611_queue_state *));
pdcp_netlink_nb_element_enb = malloc(nb_inst_enb * sizeof(uint32_t));
LOG_I(PDCP, "[NETLINK] Creating %d queues for eNB Netlink -> PDCP communication\n", nb_inst_enb);
for (i = 0; i < nb_inst_enb; i++) {
pdcp_netlink_nb_element_enb[i] = 0;
if (lfds611_queue_new(&pdcp_netlink_queue_enb[i], PDCP_QUEUE_NB_ELEMENTS) < 0) {
LOG_E(PDCP, "Failed to create new FIFO for eNB Netlink -> PDCP communcation instance %d\n", i);
exit(EXIT_FAILURE);
}
}
}
if (nb_inst_ue > 0) {
pdcp_netlink_queue_ue = calloc(nb_inst_ue, sizeof(struct lfds611_queue_state *));
pdcp_netlink_nb_element_ue = malloc(nb_inst_ue * sizeof(uint32_t));
LOG_I(PDCP, "[NETLINK] Creating %d queues for UE Netlink -> PDCP communication\n", nb_inst_ue);
for (i = 0; i < nb_inst_ue; i++) {
pdcp_netlink_nb_element_ue[i] = 0;
if (lfds611_queue_new(&pdcp_netlink_queue_ue[i], PDCP_QUEUE_NB_ELEMENTS) < 0) {
LOG_E(PDCP, "Failed to create new FIFO for UE Netlink -> PDCP communcation instance %d\n", i);
exit(EXIT_FAILURE);
}
}
}
if ((nb_inst_ue + nb_inst_enb) > 0) {
/* Create one thread that fetchs packets from the netlink.
* When the netlink fifo is full, packets are silently dropped, this behaviour
* should be avoided if we want a reliable link.
*/
threadCreate(&pdcp_netlink_thread, pdcp_netlink_thread_fct, (void*)NULL, "PDCP netlink", -1, OAI_PRIORITY_RT_LOW );
}
return 0;
}
//-----------------------------------------------------------------------------
int
pdcp_netlink_dequeue_element(
const protocol_ctxt_t *const ctxt_pP,
struct pdcp_netlink_element_s **data_ppP
)
//-----------------------------------------------------------------------------
{
int ret = 0;
if (ctxt_pP->enb_flag) {
ret = lfds611_queue_dequeue(pdcp_netlink_queue_enb[ctxt_pP->module_id], (void **)data_ppP);
if (ret != 0) {
LOG_D(PDCP,"[NETLINK]De-queueing packet for eNB instance %d\n", ctxt_pP->module_id);
}
} else {
ret = lfds611_queue_dequeue(pdcp_netlink_queue_ue[ctxt_pP->module_id], (void **)data_ppP);
if (ret != 0) {
LOG_D(PDCP, "[NETLINK]De-queueing packet for UE instance %d\n", ctxt_pP->module_id);
}
}
return ret;
}
//-----------------------------------------------------------------------------
static
void *pdcp_netlink_thread_fct(void *arg)
//-----------------------------------------------------------------------------
{
int len = 0;
struct pdcp_netlink_element_s *new_data_p = NULL;
uint8_t pdcp_thread_read_state ;
eNB_flag_t eNB_flag = 0;
module_id_t module_id = 0;
pdcp_thread_read_state = 0;
memset(nl_rx_buf, 0, NL_MAX_PAYLOAD);
LOG_I(PDCP, "[NETLINK_THREAD] binding to fd %d\n",nas_sock_fd);
while (1) {
len = recvmsg(nas_sock_fd, &nas_msg_rx, 0);
if (len == 0) {
/* Other peer (kernel) has performed an orderly shutdown
*/
LOG_E(PDCP, "[NETLINK_THREAD] Kernel module has closed the netlink\n");
exit(EXIT_FAILURE);
} else if (len < 0) {
/* There was an error */
LOG_E(PDCP, "[NETLINK_THREAD] An error occured while reading netlink (%d:%s)\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
} else {
/* Normal read.
* NOTE: netlink messages can be assembled to form a multipart message
*/
for (nas_nlh_rx = (struct nlmsghdr *) nl_rx_buf;
NLMSG_OK(nas_nlh_rx, (unsigned int)len);
nas_nlh_rx = NLMSG_NEXT (nas_nlh_rx, len)) {
start_meas(&ip_pdcp_stats_tmp);
/* There is no need to check for nlmsg_type because
* the header is not set in our drivers.
*/
if (pdcp_thread_read_state == 0) {
new_data_p = malloc(sizeof(struct pdcp_netlink_element_s));
if (nas_nlh_rx->nlmsg_len == sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)) {
pdcp_thread_read_state = 1;
memcpy((void *)&new_data_p->pdcp_read_header, (void *)NLMSG_DATA(nas_nlh_rx), sizeof(pdcp_data_req_header_t));
LOG_I(PDCP, "[NETLINK_THREAD] RX pdcp_data_req_header_t inst %u, "
"rb_id %ld data_size %d\n",
new_data_p->pdcp_read_header.inst,
new_data_p->pdcp_read_header.rb_id,
new_data_p->pdcp_read_header.data_size);
} else {
LOG_E(PDCP, "[NETLINK_THREAD] WRONG size %d should be sizeof "
"%lu ((pdcp_data_req_header_t) + sizeof(struct nlmsghdr))\n",
nas_nlh_rx->nlmsg_len,
sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr));
}
} else {
pdcp_thread_read_state = 0;
module_id = 0;
new_data_p->data = malloc(sizeof(uint8_t) * new_data_p->pdcp_read_header.data_size);
/* Copy the data */
memcpy(new_data_p->data, NLMSG_DATA(nas_nlh_rx), new_data_p->pdcp_read_header.data_size);
if (eNB_flag) {
if (pdcp_netlink_nb_element_enb[module_id]
> PDCP_QUEUE_NB_ELEMENTS) {
LOG_E(PDCP, "[NETLINK_THREAD][Mod %02x] We reached maximum number of elements in eNB pdcp queue (%lu)\n",
module_id, (intptr_t)pdcp_netlink_nb_element_enb);
}
LOG_I(PDCP,"[NETLINK_THREAD] IP->PDCP : En-queueing packet for eNB module id %d\n", module_id);
/* Enqueue the element in the right queue */
lfds611_queue_guaranteed_enqueue(pdcp_netlink_queue_enb[module_id], new_data_p);
stop_meas(&ip_pdcp_stats_tmp);
copy_meas(&eNB_pdcp_stats[module_id].pdcp_ip,&ip_pdcp_stats_tmp);
} else {
if (pdcp_netlink_nb_element_ue[module_id]
> PDCP_QUEUE_NB_ELEMENTS) {
LOG_E(PDCP, "[NETLINK_THREAD][Mod %02x] We reached maximum number of elements in UE pdcp queue (%lu)\n",
module_id, (intptr_t)pdcp_netlink_nb_element_ue);
}
LOG_I(PDCP,"[NETLINK_THREAD] IP->PDCP : En-queueing packet for UE module id %d\n", module_id);
/* Enqueue the element in the right queue */
lfds611_queue_guaranteed_enqueue(pdcp_netlink_queue_ue[module_id], new_data_p);
stop_meas(&ip_pdcp_stats_tmp);
copy_meas(&UE_pdcp_stats[module_id].pdcp_ip,&ip_pdcp_stats_tmp);
}
}
}
}
}
return NULL;
}

View File

@@ -367,14 +367,14 @@ static void enqueue_pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
if (pthread_mutex_unlock(&pq.m) != 0) abort();
}
bool pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
const rb_id_t rb_id,
const sdu_size_t sdu_buffer_size,
uint8_t *const sdu_buffer,
const uint32_t *const srcID,
const uint32_t *const dstID)
bool nr_pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
const rb_id_t rb_id,
const sdu_size_t sdu_buffer_size,
uint8_t *const sdu_buffer,
const uint32_t *const srcID,
const uint32_t *const dstID)
{
enqueue_pdcp_data_ind(ctxt_pP,
srb_flagP,
@@ -608,47 +608,26 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id)
initialized = 1;
if (pthread_mutex_unlock(&m) != 0) abort();
#if 0
pdcp_optmask = _pdcp_optmask;
return pdcp_optmask;
#endif
/* temporary enforce netlink when UE_NAS_USE_TUN is set,
this is while switching from noS1 as build option
to noS1 as config option */
if ( _pdcp_optmask & UE_NAS_USE_TUN_BIT) {
pdcp_optmask = pdcp_optmask | PDCP_USE_NETLINK_BIT ;
}
pdcp_optmask = pdcp_optmask | _pdcp_optmask ;
LOG_I(PDCP, "pdcp init,%s %s\n",
((LINK_ENB_PDCP_TO_GTPV1U)?"usegtp":""),
((PDCP_USE_NETLINK)?"usenetlink":""));
if (PDCP_USE_NETLINK) {
nas_getparams();
if(UE_NAS_USE_TUN) {
char *ifsuffix_ue = get_softmodem_params()->nsa ? "nrue" : "ue";
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF)? MAX_MOBILES_PER_ENB : 1;
netlink_init_tun(ifsuffix_ue, num_if, id);
//Add --nr-ip-over-lte option check for next line
if (IS_SOFTMODEM_NOS1){
nas_config(1, 1, !get_softmodem_params()->nsa ? 2 : 3, ifsuffix_ue);
set_qfi_pduid(7, 10);
}
LOG_I(PDCP, "UE pdcp will use tun interface\n");
start_pdcp_tun_ue();
} else if(ENB_NAS_USE_TUN) {
char *ifsuffix_base_s = get_softmodem_params()->nsa ? "gnb" : "enb";
netlink_init_tun(ifsuffix_base_s, 1, id);
nas_config(1, 1, 1, ifsuffix_base_s);
LOG_I(PDCP, "ENB pdcp will use tun interface\n");
start_pdcp_tun_enb();
} else {
LOG_I(PDCP, "pdcp will use kernel modules\n");
abort();
netlink_init();
if(UE_NAS_USE_TUN) {
char *ifprefix = get_softmodem_params()->nsa ? "oaitun_nrue" : "oaitun_ue";
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF)? MAX_MOBILES_PER_ENB : 1;
netlink_init_tun(ifprefix, num_if, id);
//Add --nr-ip-over-lte option check for next line
if (IS_SOFTMODEM_NOS1){
const char *ip = !get_softmodem_params()->nsa ? "10.0.1.2" : "10.0.1.3";
nas_config(1, AF_INET, ip, ifprefix);
set_qfi_pduid(7, 10);
}
LOG_I(PDCP, "UE pdcp will use tun interface\n");
start_pdcp_tun_ue();
} else if(ENB_NAS_USE_TUN) {
char *ifprefix = get_softmodem_params()->nsa ? "oaitun_gnb" : "oaitun_enb";
netlink_init_tun(ifprefix, 1, id);
nas_config(1, AF_INET, "10.0.1.1", ifprefix);
LOG_I(PDCP, "ENB pdcp will use tun interface\n");
start_pdcp_tun_enb();
}
return pdcp_optmask ;
}
@@ -1313,7 +1292,7 @@ bool cu_f1u_data_req(protocol_ctxt_t *ctxt_pP,
exit(1);
}
memcpy(memblock, sdu_buffer, sdu_buffer_size);
int ret=pdcp_data_ind(ctxt_pP,srb_flagP, false, rb_id, sdu_buffer_size, memblock, NULL, NULL);
int ret = nr_pdcp_data_ind(ctxt_pP, srb_flagP, false, rb_id, sdu_buffer_size, memblock, NULL, NULL);
if (!ret) {
LOG_E(RLC, "%s:%d:%s: ERROR: pdcp_data_ind failed\n", __FILE__, __LINE__, __FUNCTION__);
/* what to do in case of failure? for the moment: nothing */
@@ -1337,16 +1316,6 @@ bool pdcp_data_req(protocol_ctxt_t *ctxt_pP,
return false;
}
void pdcp_set_pdcp_data_ind_func(pdcp_data_ind_func_t pdcp_data_ind)
{
/* nothing to do */
}
void pdcp_set_rlc_data_req_func(send_rlc_data_req_func_t send_rlc_data_req)
{
/* nothing to do */
}
//Dummy function needed due to LTE dependencies
void
pdcp_mbms_run ( const protocol_ctxt_t *const ctxt_pP){

View File

@@ -37,14 +37,14 @@ void du_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
sdu_size_t sdu_sizeP,
uint8_t *sdu_pP);
bool pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
const rb_id_t rb_id,
const sdu_size_t sdu_buffer_size,
uint8_t *const sdu_buffer,
const uint32_t *const srcID,
const uint32_t *const dstID);
bool nr_pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
const rb_id_t rb_id,
const sdu_size_t sdu_buffer_size,
uint8_t *const sdu_buffer,
const uint32_t *const srcID,
const uint32_t *const dstID);
void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
ue_id_t UEid,

View File

@@ -519,7 +519,7 @@ rb_found:
}
memcpy(memblock, buf, size);
LOG_D(PDCP, "Calling PDCP layer from RLC in %s\n", __FUNCTION__);
if (!pdcp_data_ind(&ctx, is_srb, 0, rb_id, size, memblock, NULL, NULL)) {
if (!nr_pdcp_data_ind(&ctx, is_srb, 0, rb_id, size, memblock, NULL, NULL)) {
LOG_E(RLC, "%s:%d:%s: ERROR: pdcp_data_ind failed\n", __FILE__, __LINE__, __FUNCTION__);
/* what to do in case of failure? for the moment: nothing */
}

View File

@@ -418,7 +418,7 @@ rb_found:
exit(1);
}
memcpy(memblock, buf, size);
if (!get_pdcp_data_ind_func()(&ctx, is_srb, is_mbms, rb_id, size, memblock, NULL, NULL)) {
if (!pdcp_data_ind(&ctx, is_srb, is_mbms, rb_id, size, memblock, NULL, NULL)) {
LOG_E(RLC, "%s:%d:%s: ERROR: pdcp_data_ind failed (is_srb %d rb_id %d rnti %d)\n",
__FILE__, __LINE__, __FUNCTION__,
is_srb, rb_id, ue->rnti);

View File

@@ -1,11 +0,0 @@
CC = gcc
NAS_DIR = ..
rb_tool: rb_tool.c
$(CC) rb_tool.c -o rb_tool -I../ -g -ggdb
all: rb_tool
clean:
rm rb_tool

View File

@@ -1,496 +0,0 @@
/*
* 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
*/
/***************************************************************************
rb_tool.c - User-space utility for driving NASMESH IOCTL interface
-------------------
copyright : (C) 2008 by Eurecom
email : raymond.knopp@eurecom.fr and navid.nikaein@eurecom.fr
***************************************************************************
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//#include "rrc_nas_primitives.h"
#include "ioctl.h"
#include "constant.h"
#define NIPADDR(addr) \
(uint8_t)(addr & 0x000000FF), \
(uint8_t)((addr & 0x0000FF00) >> 8), \
(uint8_t)((addr & 0x00FF0000) >> 16), \
(uint8_t)((addr & 0xFF000000) >> 24)
#define NIP6ADDR(addr) \
ntohs((addr)->s6_addr16[0]), \
ntohs((addr)->s6_addr16[1]), \
ntohs((addr)->s6_addr16[2]), \
ntohs((addr)->s6_addr16[3]), \
ntohs((addr)->s6_addr16[4]), \
ntohs((addr)->s6_addr16[5]), \
ntohs((addr)->s6_addr16[6]), \
ntohs((addr)->s6_addr16[7])
// Global variables
int fd;
//ioctl
char dummy_buffer[1024];
struct oai_nw_drv_ioctl gifr;
//int wait_start_nas;
//---------------------------------------------------------------------------
void IAL_NAS_ioctl_init(int inst)
//---------------------------------------------------------------------------
{
struct oai_nw_drv_msg_statistic_reply *msgrep;
int err,rc;
sprintf(gifr.name, "oai%d",inst);
// Get an UDP IPv6 socket ??
fd=socket(AF_INET6, SOCK_DGRAM, 0);
if (fd<0) {
printf("Error opening socket\n");
exit(1);
}
sprintf(gifr.name, "oai%d",inst);
gifr.type = OAI_NW_DRV_MSG_STATISTIC_REQUEST;
memset ((void *)dummy_buffer,0,800);
gifr.msg= &(dummy_buffer[0]);
msgrep=(struct oai_nw_drv_msg_statistic_reply *)(gifr.msg);
printf("ioctl :Statistics requested\n");
err=ioctl(fd, OAI_NW_DRV_IOCTL_RRM, &gifr);
if (err<0) {
printf("IOCTL error, err=%d\n",err);
rc = -1;
}
printf("tx_packets = %u, rx_packets = %u\n", msgrep->tx_packets, msgrep->rx_packets);
printf("tx_bytes = %u, rx_bytes = %u\n", msgrep->tx_bytes, msgrep->rx_bytes);
printf("tx_errors = %u, rx_errors = %u\n", msgrep->tx_errors, msgrep->rx_errors);
printf("tx_dropped = %u, rx_dropped = %u\n", msgrep->tx_dropped, msgrep->rx_dropped);
}
#define NO_ACTION_RB 0
#define ADD_RB 1
#define DEL_RB 2
//---------------------------------------------------------------------------
int main(int argc,char **argv)
//---------------------------------------------------------------------------
{
int done;
int rc;
int meas_polling_counter;
fd_set readfds;
struct timeval tv;
int i;
int err;
char *buffer;
int c;
int action;
int rbset = 0;
int cxset = 0;
int classrefset = 0;
int instset = 0;
int saddr_ipv4set = 0;
int saddr_ipv6set = 0;
int daddr_ipv4set = 0;
int daddr_ipv6set = 0;
int dscpset = 0;
int dplen = 0;
int splen = 0;
int mpls_outlabelset = 0;
int mpls_inlabelset;
char rb[20];
char cx[20];
char classref[20];
char dscp[20];
char inst[20];
char mpls_outgoinglabel[100];
char mpls_incominglabel[100];
int index;
struct oai_nw_drv_msg_rb_establishment_request *msgreq;
struct oai_nw_drv_msg_class_add_request *msgreq_class;
in_addr_t saddr_ipv4;
in_addr_t daddr_ipv4;
struct in6_addr saddr_ipv6;
struct in6_addr daddr_ipv6;
unsigned int mpls_outlabel;
unsigned int mpls_inlabel;
char addr_str[46];
char mask_len_delims[] = "/";
char *result;
// scan options
rb[0] = '\0';
cx[0] = '\0';
dscp[0] = '\0';
mpls_incominglabel[0] = '\0';
mpls_outgoinglabel[0] = '\0';
action = NO_ACTION_RB;
while ((c = getopt (argc, argv, "adr:i:c:f:l:m:s:t:x:y:z:")) != -1)
switch (c) {
case 'a':
action = ADD_RB;
break;
case 'd':
action = DEL_RB;
break;
case 'r':
strcpy(rb,optarg);
rbset = 1;
break;
case 'i':
strcpy(inst,optarg);
instset = 1;
break;
case 'c':
strcpy(cx,optarg);
cxset = 1;
break;
case 'f':
strcpy(classref,optarg);
classrefset = 1;
break;
case 'l':
strcpy(mpls_outgoinglabel,optarg);
mpls_outlabelset=1;
break;
case 'm':
strcpy(mpls_incominglabel,optarg);
mpls_inlabelset=1;
break;
case 's':
result = strtok( optarg, mask_len_delims );
if ( result != NULL ) {
inet_aton(result,&saddr_ipv4);
printf("Arg Source Addr IPv4 string: %s\n",result);
saddr_ipv4set = 1;
} else {
printf("Arg Source Addr IPv4 string: ERROR\n");
break;
}
result = strtok( NULL, mask_len_delims );
if ( result != NULL ) {
splen = atoi(result);
} else {
splen = 32;
}
printf("Arg Source Addr IPv4 mask len: %d\n",splen);
break;
case 't':
result = strtok( optarg, mask_len_delims );
if ( result != NULL ) {
inet_aton(result,&daddr_ipv4);
printf("Arg Dest Addr IPv4 string: %s\n",result);
daddr_ipv4set = 1;
} else {
printf("Arg Dest Addr IPv4 string: ERROR\n");
break;
}
result = strtok( NULL, mask_len_delims );
if ( result != NULL ) {
dplen = atoi(result);
} else {
dplen = 32;
}
printf("Arg Dest Addr IPv4 mask len: %d\n",dplen);
break;
case 'x':
result = strtok( optarg, mask_len_delims );
if ( result != NULL ) {
printf("Arg Source Addr IPv6 string: %s\n",result);
inet_pton(AF_INET6,result,(void *)&saddr_ipv6);
saddr_ipv6set = 1;
} else {
printf("Arg Source Addr IPv6 string: ERROR\n");
break;
}
result = strtok( NULL, mask_len_delims );
if ( result != NULL ) {
splen = atoi(result);
} else {
splen = 128;
}
printf("Arg Source Addr IPv6 mask len: %d\n",splen);
break;
case 'y':
result = strtok( optarg, mask_len_delims );
if ( result != NULL ) {
printf("Arg Dest Addr IPv6 string: %s\n",result);
inet_pton(AF_INET6,result,(void *)&daddr_ipv6);
daddr_ipv6set = 1;
} else {
printf("Arg Dest Addr IPv6 string: ERROR\n");
break;
}
result = strtok( NULL, mask_len_delims );
if ( result != NULL ) {
dplen = atoi(result);
} else {
dplen = 128;
}
printf("Arg Dest Addr IPv6 mask len: %d\n",dplen);
break;
case 'z':
dscpset=1;
strcpy(dscp,optarg);
break;
case '?':
if (isprint (optopt))
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf (stderr,
"Unknown option character `\\x%x'.\n",
optopt);
return 1;
default:
abort ();
}
printf ("action = %d, rb = %s,cx = %s\n", action, rb, cx);
if (rbset==0) {
printf("ERROR: Specify a RAB id!!\n");
exit(-1);
}
if (cxset==0) {
printf("ERROR: Specify an LCR !!\n");
exit(-1);
}
if (classrefset==0) {
printf("ERROR: Specify an Class reference !!\n");
exit(-1);
}
if (instset==0) {
printf("ERROR: Specify an interface !!\n");
exit(-1);
}
if ((mpls_outlabelset == 0) && (saddr_ipv4set==0) && (saddr_ipv6set==0)) {
printf("ERROR: Specify a source IP address\n");
exit(-1);
}
if ((mpls_outlabelset == 0) && (daddr_ipv4set==0) && (daddr_ipv6set==0)) {
printf("ERROR: Specify a destination IP address\n");
exit(-1);
}
if ((mpls_outlabelset == 1) && (mpls_inlabelset == 0)) {
printf("ERROR: Specify an incoming MPLS label\n");
exit(-1);
}
if ((mpls_inlabelset == 1) && (mpls_outlabelset == 0)) {
printf("ERROR: Specify an outgoing MPLS label\n");
exit(-1);
}
IAL_NAS_ioctl_init(atoi(inst));
msgreq = (struct oai_nw_drv_msg_rb_establishment_request *)(gifr.msg);
msgreq->rab_id = atoi(rb);
msgreq->lcr = atoi(cx);
msgreq->qos = 0;
if (action == ADD_RB) {
gifr.type = OAI_NW_DRV_MSG_RB_ESTABLISHMENT_REQUEST;
printf("OAI_NW_DRV_MSG_RB_ESTABLISHMENT_REQUEST: RB %d LCR %d QOS %d\n ", msgreq->rab_id, msgreq->lcr, msgreq->qos);
err=ioctl(fd, OAI_NW_DRV_IOCTL_RRM, &gifr);
}
// only add classification rule
if ((action == ADD_RB ) || (action == NO_ACTION_RB)) {
if (saddr_ipv4set == 1) {
msgreq_class = (struct oai_nw_drv_msg_class_add_request *)(gifr.msg);
msgreq_class->rab_id = atoi(rb);
msgreq_class->lcr = atoi(cx);
msgreq_class->version = 4;
msgreq_class->classref = atoi(classref) + (msgreq_class->lcr<<8);
msgreq_class->dir = OAI_NW_DRV_DIRECTION_SEND;
msgreq_class->fct = OAI_NW_DRV_FCT_QOS_SEND;
msgreq_class->saddr.ipv4 = saddr_ipv4;
msgreq_class->daddr.ipv4 = daddr_ipv4;
msgreq_class->dplen = dplen;
msgreq_class->splen = splen;
// TO BE FIXED WHEN WE CAN SPECIFY A PROTOCOL-based rule
msgreq_class->protocol = OAI_NW_DRV_PROTOCOL_DEFAULT;
if (dscpset==0) {
msgreq_class->dscp=0;
} else {
msgreq_class->dscp=atoi(dscp);
}
printf("OAI_NW_DRV_MSG_CLASS_ADD_REQUEST: OAI_NW_DRV_DIRECTION_SEND RB %d LCR %d ClassRef %d ", msgreq_class->rab_id, msgreq_class->lcr, msgreq_class->classref);
printf("IPV4: Source = %d.%d.%d.%d/%d ", NIPADDR(msgreq_class->saddr.ipv4), msgreq_class->splen);
printf(" IPV4: Dest = %d.%d.%d.%d/%d\n", NIPADDR(msgreq_class->daddr.ipv4), msgreq_class->dplen);
gifr.type = OAI_NW_DRV_MSG_CLASS_ADD_REQUEST;
err=ioctl(fd, OAI_NW_DRV_IOCTL_RRM, &gifr);
msgreq_class->rab_id = atoi(rb);
msgreq_class->lcr = atoi(cx);
msgreq_class->version = 4;
msgreq_class->classref = atoi(classref) + 1 + (msgreq_class->lcr<<8);
msgreq_class->dir = OAI_NW_DRV_DIRECTION_RECEIVE;
msgreq_class->fct = OAI_NW_DRV_FCT_QOS_SEND;
msgreq_class->daddr.ipv4 = saddr_ipv4;
msgreq_class->saddr.ipv4 = daddr_ipv4;
msgreq_class->dplen = splen;
msgreq_class->splen = dplen;
printf("OAI_NW_DRV_MSG_CLASS_ADD_REQUEST: OAI_NW_DRV_DIRECTION_RECEIVE RB %d LCR %d ClassRef %d ", msgreq_class->rab_id, msgreq_class->lcr, msgreq_class->classref);
printf("IPV4: Source = %d.%d.%d.%d/%d ", NIPADDR(msgreq_class->saddr.ipv4), msgreq_class->splen);
printf("IPV4: Dest = %d.%d.%d.%d/%d\n", NIPADDR(msgreq_class->daddr.ipv4), msgreq_class->dplen);
gifr.type = OAI_NW_DRV_MSG_CLASS_ADD_REQUEST;
err=ioctl(fd, OAI_NW_DRV_IOCTL_RRM, &gifr);
}
if (saddr_ipv6set == 1) {
msgreq_class = (struct oai_nw_drv_msg_class_add_request *)(gifr.msg);
msgreq_class->rab_id = atoi(rb);
msgreq_class->lcr = atoi(cx);
msgreq_class->version = 6;
msgreq_class->dplen = dplen;
msgreq_class->splen = splen;
if (dscpset==0)
msgreq_class->dscp = 0;
else
msgreq_class->dscp = atoi(dscp);
msgreq_class->classref = atoi(classref) + (msgreq_class->lcr<<8);
msgreq_class->dir = OAI_NW_DRV_DIRECTION_SEND;
msgreq_class->fct = OAI_NW_DRV_FCT_QOS_SEND;
// TO BE FIXED WHEN WE CAN SPECIFY A PROTOCOL-based rule
msgreq_class->protocol = OAI_NW_DRV_PROTOCOL_DEFAULT;
memcpy(&msgreq_class->saddr.ipv6,&saddr_ipv6,16);
memcpy(&msgreq_class->daddr.ipv6,&daddr_ipv6,16);
printf("OAI_NW_DRV_MSG_CLASS_ADD_REQUEST: OAI_NW_DRV_DIRECTION_SEND RB %d LCR %d ClassRef %d ", msgreq_class->rab_id, msgreq_class->lcr, msgreq_class->classref);
printf("IPV6: Source = %x:%x:%x:%x:%x:%x:%x:%x/%d ", NIP6ADDR(&msgreq_class->saddr.ipv6), msgreq_class->splen);
printf("IPV6: Dest = %x:%x:%x:%x:%x:%x:%x:%x/%d\n", NIP6ADDR(&msgreq_class->daddr.ipv6), msgreq_class->dplen);
gifr.type = OAI_NW_DRV_MSG_CLASS_ADD_REQUEST;
err=ioctl(fd, OAI_NW_DRV_IOCTL_RRM, &gifr);
msgreq_class->rab_id = atoi(rb);
msgreq_class->lcr = atoi(cx);
msgreq_class->dplen = splen;
msgreq_class->splen = dplen;
msgreq_class->classref = atoi(classref) + 1 + (msgreq_class->lcr<<8);
msgreq_class->dir = OAI_NW_DRV_DIRECTION_RECEIVE;
memcpy(&msgreq_class->daddr.ipv6,&saddr_ipv6,16);
memcpy(&msgreq_class->saddr.ipv6,&daddr_ipv6,16);
printf("OAI_NW_DRV_MSG_CLASS_ADD_REQUEST: OAI_NW_DRV_DIRECTION_RECEIVE RB %d LCR %d ClassRef %d ", msgreq_class->rab_id, msgreq_class->lcr, msgreq_class->classref);
printf("IPV6: Source = %x:%x:%x:%x:%x:%x:%x:%x/%d ", NIP6ADDR(&msgreq_class->saddr.ipv6), msgreq_class->splen);
printf("IPV6: Dest = %x:%x:%x:%x:%x:%x:%x:%x/%d\n", NIP6ADDR(&msgreq_class->daddr.ipv6), msgreq_class->dplen);
gifr.type = OAI_NW_DRV_MSG_CLASS_ADD_REQUEST;
err=ioctl(fd, OAI_NW_DRV_IOCTL_RRM, &gifr);
}
if (mpls_inlabelset == 1) {
msgreq_class = (struct oai_nw_drv_msg_class_add_request *)(gifr.msg);
msgreq_class->rab_id = atoi(rb);
msgreq_class->lcr = atoi(cx);
msgreq_class->version = OAI_NW_DRV_MPLS_VERSION_CODE;
if (dscpset==0)
msgreq_class->dscp=0;
else
msgreq_class->dscp=atoi(dscp);
msgreq_class->classref = atoi(classref) + (msgreq_class->lcr<<8);
//msgreq_class->classref = 4 + (msgreq_class->lcr<<3);
msgreq_class->dir=OAI_NW_DRV_DIRECTION_SEND;
msgreq_class->fct=OAI_NW_DRV_FCT_QOS_SEND;
// TO BE FIXED WHEN WE CAN SPECIFY A PROTOCOL-based rule
msgreq_class->protocol = OAI_NW_DRV_PROTOCOL_DEFAULT;
mpls_outlabel = atoi(mpls_outgoinglabel);
printf("Setting MPLS outlabel %u with exp %d\n",mpls_outlabel,msgreq_class->dscp);
msgreq_class->daddr.mpls_label = mpls_outlabel;
gifr.type = OAI_NW_DRV_MSG_CLASS_ADD_REQUEST;
err=ioctl(fd, OAI_NW_DRV_IOCTL_RRM, &gifr);
msgreq_class->rab_id = atoi(rb);
msgreq_class->lcr = atoi(cx);
msgreq_class->classref = atoi(classref) + 1 + (msgreq_class->lcr<<8);
//msgreq_class->classref = 5 + (msgreq_class->lcr<<3);
msgreq_class->dir=OAI_NW_DRV_DIRECTION_RECEIVE;
// TO BE FIXED WHEN WE CAN SPECIFY A PROTOCOL-based rule
msgreq_class->protocol = OAI_NW_DRV_PROTOCOL_DEFAULT;
mpls_inlabel = atoi(mpls_incominglabel);
printf("Setting MPLS inlabel %u with exp %d\n",mpls_inlabel,msgreq_class->dscp);
msgreq_class->daddr.mpls_label = mpls_inlabel;
gifr.type = OAI_NW_DRV_MSG_CLASS_ADD_REQUEST;
err=ioctl(fd, OAI_NW_DRV_IOCTL_RRM, &gifr);
}
} else if (action == DEL_RB) {
gifr.type = OAI_NW_DRV_MSG_RB_RELEASE_REQUEST;
err=ioctl(fd, OAI_NW_DRV_IOCTL_RRM, &gifr);
}
}

View File

@@ -1,194 +0,0 @@
/*
* 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
*/
/*! \file classifier.c
* \brief Classify IP packets
* \author Navid Nikaein, Lionel GAUTHIER, Raymond knopp
* \company Eurecom
* \email: navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr, knopp@eurecom.fr
*/
#include "local.h"
#include "proto_extern.h"
#include <net/ip6_fib.h>
#include <net/route.h>
#ifdef MPLS
#include <net/mpls.h>
#endif
#define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0)
#define IN_CLASSB(a) ((((long int) (a)) & 0xc0000000) == 0x80000000)
#define IN_CLASSC(a) ((((long int) (a)) & 0xe0000000) == 0xc0000000)
#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
#define IN_MULTICAST(a) IN_CLASSD(a)
#define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
#define IN_BADCLASS(a) IN_EXPERIMENTAL((a))
/* Address to accept any incoming messages. */
#define INADDR_ANY ((unsigned long int) 0x00000000)
/* Address to send to all hosts. */
#define INADDR_BROADCAST ((unsigned long int) 0xffffffff)
/* Address indicating an error return. */
#define INADDR_NONE ((unsigned long int) 0xffffffff)
#define NIPADDR(addr) \
(uint8_t)(addr & 0x000000FF), \
(uint8_t)((addr & 0x0000FF00) >> 8), \
(uint8_t)((addr & 0x00FF0000) >> 16), \
(uint8_t)((addr & 0xFF000000) >> 24)
#define NIP6ADDR(addr) \
ntohs((addr)->s6_addr16[0]), \
ntohs((addr)->s6_addr16[1]), \
ntohs((addr)->s6_addr16[2]), \
ntohs((addr)->s6_addr16[3]), \
ntohs((addr)->s6_addr16[4]), \
ntohs((addr)->s6_addr16[5]), \
ntohs((addr)->s6_addr16[6]), \
ntohs((addr)->s6_addr16[7])
#define IN6_IS_ADDR_UNSPECIFIED(a) \
(((__const uint32_t *) (a))[0] == 0 \
&& ((__const uint32_t *) (a))[1] == 0 \
&& ((__const uint32_t *) (a))[2] == 0 \
&& ((__const uint32_t *) (a))[3] == 0)
#define IN6_IS_ADDR_LOOPBACK(a) \
(((__const uint32_t *) (a))[0] == 0 \
&& ((__const uint32_t *) (a))[1] == 0 \
&& ((__const uint32_t *) (a))[2] == 0 \
&& ((__const uint32_t *) (a))[3] == htonl (1))
#define IN6_IS_ADDR_MULTICAST(a) (((__const uint8_t *) (a))[0] == 0xff)
#define IN6_IS_ADDR_LINKLOCAL(a) \
((((__const uint32_t *) (a))[0] & htonl (0xffc00000)) \
== htonl (0xfe800000))
#define IN6_IS_ADDR_SITELOCAL(a) \
((((__const uint32_t *) (a))[0] & htonl (0xffc00000)) \
== htonl (0xfec00000))
#define IN6_IS_ADDR_V4MAPPED(a) \
((((__const uint32_t *) (a))[0] == 0) \
&& (((__const uint32_t *) (a))[1] == 0) \
&& (((__const uint32_t *) (a))[2] == htonl (0xffff)))
#define IN6_IS_ADDR_V4COMPAT(a) \
((((__const uint32_t *) (a))[0] == 0) \
&& (((__const uint32_t *) (a))[1] == 0) \
&& (((__const uint32_t *) (a))[2] == 0) \
&& (ntohl (((__const uint32_t *) (a))[3]) > 1))
#define IN6_ARE_ADDR_EQUAL(a,b) \
((((__const uint32_t *) (a))[0] == ((__const uint32_t *) (b))[0]) \
&& (((__const uint32_t *) (a))[1] == ((__const uint32_t *) (b))[1]) \
&& (((__const uint32_t *) (a))[2] == ((__const uint32_t *) (b))[2]) \
&& (((__const uint32_t *) (a))[3] == ((__const uint32_t *) (b))[3]))
#define IN6_IS_ADDR_MC_NODELOCAL(a) \
(IN6_IS_ADDR_MULTICAST(a) \
&& ((((__const uint8_t *) (a))[1] & 0xf) == 0x1))
#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
(IN6_IS_ADDR_MULTICAST(a) \
&& ((((__const uint8_t *) (a))[1] & 0xf) == 0x2))
#define IN6_IS_ADDR_MC_SITELOCAL(a) \
(IN6_IS_ADDR_MULTICAST(a) \
&& ((((__const uint8_t *) (a))[1] & 0xf) == 0x5))
#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
(IN6_IS_ADDR_MULTICAST(a) \
&& ((((__const uint8_t *) (a))[1] & 0xf) == 0x8))
#define IN6_IS_ADDR_MC_GLOBAL(a) \
(IN6_IS_ADDR_MULTICAST(a) \
&& ((((__const uint8_t *) (a))[1] & 0xf) == 0xe))
#define IN6_ARE_ADDR_MASKED_EQUAL(a,b,m) \
(((((__const uint32_t *) (a))[0] & (((__const uint32_t *) (m))[0])) == (((__const uint32_t *) (b))[0] & (((__const uint32_t *) (m))[0]))) \
&& ((((__const uint32_t *) (a))[1] & (((__const uint32_t *) (m))[1])) == (((__const uint32_t *) (b))[1] & (((__const uint32_t *) (m))[1]))) \
&& ((((__const uint32_t *) (a))[2] & (((__const uint32_t *) (m))[2])) == (((__const uint32_t *) (b))[2] & (((__const uint32_t *) (m))[2]))) \
&& ((((__const uint32_t *) (a))[3] & (((__const uint32_t *) (m))[3])) == (((__const uint32_t *) (b))[3] & (((__const uint32_t *) (m))[3]))))
#define IN_ARE_ADDR_MASKED_EQUAL(a,b,m) \
(((((__const uint8_t *) (a))[0] & (((__const uint8_t *) (m))[0])) == (((__const uint8_t *) (b))[0] & (((__const uint8_t *) (m))[0]))) \
&& ((((__const uint8_t *) (a))[1] & (((__const uint8_t *) (m))[1])) == (((__const uint8_t *) (b))[1] & (((__const uint8_t *) (m))[1]))) \
&& ((((__const uint8_t *) (a))[2] & (((__const uint8_t *) (m))[2])) == (((__const uint8_t *) (b))[2] & (((__const uint8_t *) (m))[2]))) \
&& ((((__const uint8_t *) (a))[3] & (((__const uint8_t *) (m))[3])) == (((__const uint8_t *) (b))[3] & (((__const uint8_t *) (m))[3]))))
//---------------------------------------------------------------------------
// Find the IP traffic type (UNICAST, MULTICAST, BROADCAST)
ip_traffic_type_t oai_nw_drv_find_traffic_type(struct sk_buff *skb)
{
//---------------------------------------------------------------------------
ip_traffic_type_t traffic_type = TRAFFIC_IPVX_TYPE_UNKNOWN;
if (skb!=NULL) {
switch (ntohs(skb->protocol)) {
case ETH_P_IPV6:
traffic_type = TRAFFIC_IPV6_TYPE_UNKNOWN;
#ifdef OAI_DRV_DEBUG_CLASS
printk("SOURCE ADDR %X:%X:%X:%X:%X:%X:%X:%X",NIP6ADDR(&(ipv6_hdr(skb)->saddr)));
printk(" DEST ADDR %X:%X:%X:%X:%X:%X:%X:%X\n",NIP6ADDR(&(ipv6_hdr(skb)->daddr)));
#endif
if (IN6_IS_ADDR_MULTICAST(&ipv6_hdr(skb)->daddr.in6_u.u6_addr32[0])) {
traffic_type = TRAFFIC_IPV6_TYPE_MULTICAST;
} else {
traffic_type = TRAFFIC_IPV6_TYPE_UNICAST;
}
break;
case ETH_P_IP:
traffic_type = TRAFFIC_IPV4_TYPE_UNKNOWN;
//print_TOOL_pk_ipv4((struct iphdr *)skb->network_header);
if (IN_MULTICAST(htonl(ip_hdr(skb)->daddr))) {
traffic_type = TRAFFIC_IPV4_TYPE_MULTICAST;
} else {
traffic_type = TRAFFIC_IPV4_TYPE_UNICAST;
}
// TO DO BROADCAST
break;
case ETH_P_ARP:
traffic_type = TRAFFIC_IPV4_TYPE_BROADCAST;
break;
default:
;
}
}
return traffic_type;
}

View File

@@ -1,451 +0,0 @@
/*
* 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
*/
/*! \file common.c
* \brief implementation of emultor tx and rx
* \author Navid Nikaein, Lionel GAUTHIER, and Raymomd Knopp
* \date 2011
* \version 1.0
* \company Eurecom
* \email: navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
#include "local.h"
#include "proto_extern.h"
#ifndef OAI_NW_DRIVER_USE_NETLINK
#include "rtai_fifos.h"
#endif
#include <linux/inetdevice.h>
#ifdef OAI_NW_DRIVER_TYPE_ETHERNET
#include <linux/etherdevice.h>
#endif
#include <net/tcp.h>
#include <net/udp.h>
#define NIPADDR(addr) \
(uint8_t)(addr & 0x000000FF), \
(uint8_t)((addr & 0x0000FF00) >> 8), \
(uint8_t)((addr & 0x00FF0000) >> 16), \
(uint8_t)((addr & 0xFF000000) >> 24)
#define NIP6ADDR(addr) \
ntohs((addr)->s6_addr16[0]), \
ntohs((addr)->s6_addr16[1]), \
ntohs((addr)->s6_addr16[2]), \
ntohs((addr)->s6_addr16[3]), \
ntohs((addr)->s6_addr16[4]), \
ntohs((addr)->s6_addr16[5]), \
ntohs((addr)->s6_addr16[6]), \
ntohs((addr)->s6_addr16[7])
//#define OAI_DRV_DEBUG_SEND
//#define OAI_DRV_DEBUG_RECEIVE
void oai_nw_drv_common_class_wireless2ip(uint16_t dlen,
void *pdcp_sdu,
int inst,
OaiNwDrvRadioBearerId_t rb_id)
{
//---------------------------------------------------------------------------
struct sk_buff *skb;
struct ipversion *ipv;
struct oai_nw_drv_priv *gpriv=netdev_priv(oai_nw_drv_dev[inst]);
unsigned int hard_header_len = 0;
uint16_t *p_ether_type;
uint16_t ether_type;
#ifdef OAI_DRV_DEBUG_RECEIVE
int i;
unsigned char *addr;
#endif
unsigned char protocol;
struct iphdr *network_header;
#ifdef NAS_ADDRESS_FIX
uint32_t odaddr,osaddr;
unsigned char *addr,*daddr,*saddr,*ifaddr;
uint16_t *cksum,check;
#endif // NAS_ADDRESS_FIX
#ifdef OAI_DRV_DEBUG_RECEIVE
printk("[OAI_IP_DRV][%s] begin RB %d Inst %d Length %d bytes\n",__FUNCTION__, rb_id,inst,dlen);
#endif
skb = dev_alloc_skb( dlen + 2 );
if(!skb) {
printk("[OAI_IP_DRV][%s] low on memory\n",__FUNCTION__);
++gpriv->stats.rx_dropped;
return;
}
skb_reserve(skb,2);
memcpy(skb_put(skb, dlen), pdcp_sdu,dlen);
skb->dev = oai_nw_drv_dev[inst];
hard_header_len = oai_nw_drv_dev[inst]->hard_header_len;
skb_set_mac_header(skb, 0);
skb_set_network_header(skb, hard_header_len);
skb->mark = rb_id;
skb->pkt_type = PACKET_HOST;
#ifdef OAI_DRV_DEBUG_RECEIVE
printk("[OAI_IP_DRV][%s] Receiving packet @%p of size %d from PDCP \n",__FUNCTION__, skb->data, skb->len);
for (i=0; i<skb->len; i++)
printk("%2x ",((unsigned char *)(skb->data))[i]);
printk("\n");
#endif
// LG TEST skb->ip_summed = CHECKSUM_NONE;
skb->ip_summed = CHECKSUM_UNNECESSARY;
ipv = (struct ipversion *)skb_network_header(skb);
switch (ipv->version) {
case 6:
#ifdef OAI_DRV_DEBUG_RECEIVE
printk("[OAI_IP_DRV][%s] receive IPv6 message\n",__FUNCTION__);
#endif
skb_set_network_header(skb, hard_header_len);
//skb->network_header = &skb->data[hard_header_len];
if (hard_header_len == 0) {
skb->protocol = htons(ETH_P_IPV6);
} else {
#ifdef OAI_NW_DRIVER_TYPE_ETHERNET
skb->protocol = eth_type_trans(skb, oai_nw_drv_dev[inst]);
#else
#endif
}
//printk("Writing packet with protocol %x\n",ntohs(skb->protocol));
break;
case 4:
#ifdef NAS_ADDRESS_FIX
// Make the third byte of both the source and destination equal to the fourth of the destination
daddr = (unsigned char *)&((struct iphdr *)&skb->data[hard_header_len])->daddr;
odaddr = ((struct iphdr *)skb->data)->daddr;
//sn = addr[3];
saddr = (unsigned char *)&((struct iphdr *)&skb->data[hard_header_len])->saddr;
osaddr = ((struct iphdr *)&skb->data[hard_header_len])->saddr;
if (daddr[0] == saddr[0]) {// same network
daddr[2] = daddr[3]; // set third byte of destination to that of local machine so that local IP stack accepts the packet
saddr[2] = daddr[3]; // set third byte of source to that of local machine so that local IP stack accepts the packet
} else { // get the 3rd byte from device address in net_device structure
ifaddr = (unsigned char *)(&(((struct in_device *)((oai_nw_drv_dev[inst])->ip_ptr))->ifa_list->ifa_local));
if (saddr[0] == ifaddr[0]) { // source is in same network as local machine
daddr[0] += saddr[3]; // fix address of remote destination to undo change at source
saddr[2] = ifaddr[2]; // set third byte to that of local machine so that local IP stack accepts the packet
} else { // source is remote machine from outside network
saddr[0] -= daddr[3]; // fix address of remote source to be understood by destination
daddr[2] = daddr[3]; // fix 3rd byte of local address to be understood by IP stack of
// destination
}
}
#endif //NAS_ADDRESS_FIX
#ifdef OAI_DRV_DEBUG_RECEIVE
//printk("NAS_TOOL_RECEIVE: receive IPv4 message\n");
addr = (unsigned char *)&((struct iphdr *)&skb->data[hard_header_len])->saddr;
if (addr) {
//addr[2]^=0x01;
printk("[OAI_IP_DRV][%s] Source %d.%d.%d.%d\n",__FUNCTION__, addr[0],addr[1],addr[2],addr[3]);
}
addr = (unsigned char *)&((struct iphdr *)&skb->data[hard_header_len])->daddr;
if (addr) {
//addr[2]^=0x01;
printk("[OAI_IP_DRV][%s] Dest %d.%d.%d.%d\n",__FUNCTION__, addr[0],addr[1],addr[2],addr[3]);
}
printk("[OAI_IP_DRV][%s] protocol %d\n",__FUNCTION__, ((struct iphdr *)&skb->data[hard_header_len])->protocol);
#endif
skb_set_network_header(skb, hard_header_len);
//skb->network_header = &skb->data[hard_header_len];
network_header = (struct iphdr *)skb_network_header(skb);
protocol = network_header->protocol;
#ifdef OAI_DRV_DEBUG_RECEIVE
switch (protocol) {
case IPPROTO_IP:
printk("[OAI_IP_DRV][%s] Received Raw IPv4 packet\n",__FUNCTION__);
break;
case IPPROTO_IPV6:
printk("[OAI_IP_DRV][%s] Received Raw IPv6 packet\n",__FUNCTION__);
break;
case IPPROTO_ICMP:
printk("[OAI_IP_DRV][%s] Received Raw ICMP packet\n",__FUNCTION__);
break;
case IPPROTO_TCP:
printk("[OAI_IP_DRV][%s] Received TCP packet\n",__FUNCTION__);
break;
case IPPROTO_UDP:
printk("[OAI_IP_DRV][%s] Received UDP packet\n",__FUNCTION__);
break;
default:
break;
}
#endif
#ifdef NAS_ADDRESS_FIX
network_header->check = 0;
network_header->check = ip_fast_csum((unsigned char *) network_header, network_header->ihl);
//printk("[OAI_IP_DRV][COMMON][RECEIVE] IP Fast Checksum %x \n", network_header->check);
switch(protocol) {
case IPPROTO_TCP:
cksum = (uint16_t*)&(((struct tcphdr*)((network_header + (network_header->ihl<<2))))->check);
check = csum_tcpudp_magic(((struct iphdr *)network_header)->saddr, ((struct iphdr *)network_header)->daddr, 0,0, ~(*cksum));
//check = csum_tcpudp_magic(((struct iphdr *)network_header)->saddr, ((struct iphdr *)network_header)->daddr, tcp_hdrlen(skb), IPPROTO_TCP, ~(*cksum));
//check = csum_tcpudp_magic(((struct iphdr *)network_header)->saddr, ((struct iphdr *)network_header)->daddr, dlen, IPPROTO_TCP, ~(*cksum));
*cksum = csum_tcpudp_magic(~osaddr, ~odaddr, 0, 0, ~check);
//*cksum = csum_tcpudp_magic(~osaddr, ~odaddr, dlen, IPPROTO_TCP, ~check);
#ifdef OAI_DRV_DEBUG_RECEIVE
printk("[OAI_IP_DRV][%s] Inst %d TCP packet calculated CS %x, CS = %x (before), SA (%x)%x, DA (%x)%x\n",__FUNCTION__,
inst,
network_header->check,
*cksum,
osaddr,
((struct iphdr *)skb->data)->saddr,
odaddr,
((struct iphdr *)skb->data)->daddr);
printk("[OAI_IP_DRV][%s] Inst %d TCP packet NEW CS %x\n",__FUNCTION__,
inst,
*cksum);
#endif
break;
case IPPROTO_UDP:
cksum = (uint16_t*)&(((struct udphdr*)((network_header + (network_header->ihl<<2))))->check);
check = csum_tcpudp_magic(((struct iphdr *)network_header)->saddr, ((struct iphdr *)network_header)->daddr, 0,0, ~(*cksum));
// check = csum_tcpudp_magic(((struct iphdr *)network_header)->saddr, ((struct iphdr *)network_header)->daddr, udp_hdr(skb)->len, IPPROTO_UDP, ~(*cksum));
//check = csum_tcpudp_magic(((struct iphdr *)network_header)->saddr, ((struct iphdr *)network_header)->daddr, dlen, IPPROTO_UDP, ~(*cksum));
*cksum= csum_tcpudp_magic(~osaddr, ~odaddr,0,0, ~check);
//*cksum= csum_tcpudp_magic(~osaddr, ~odaddr,udp_hdr(skb)->len, IPPROTO_UDP, ~check);
//*cksum= csum_tcpudp_magic(~osaddr, ~odaddr,dlen, IPPROTO_UDP, ~check);
#ifdef OAI_DRV_DEBUG_RECEIVE
printk("[OAI_IP_DRV][%s] Inst %d UDP packet CS = %x (before), SA (%x)%x, DA (%x)%x\n",__FUNCTION__,
inst,*cksum,osaddr,((struct iphdr *)&skb->data[hard_header_len])->saddr,odaddr,((struct iphdr *)&skb->data[hard_header_len])->daddr);
printk("[OAI_IP_DRV][%s] Inst %d UDP packet NEW CS %x\n",__FUNCTION__,inst,*cksum);
#endif
//if ((check = *cksum) != 0) {
// src, dst, len, proto, sum
// }
break;
default:
break;
}
#endif //NAS_ADDRESS_FIX
if (hard_header_len == 0) {
skb->protocol = htons(ETH_P_IP);
} else {
#ifdef OAI_NW_DRIVER_TYPE_ETHERNET
skb->protocol = eth_type_trans(skb, oai_nw_drv_dev[inst]);
#else
#endif
}
//printk("[OAI_IP_DRV][COMMON] Writing packet with protocol %x\n",ntohs(skb->protocol));
break;
default:
// fill skb->pkt_type, skb->dev
skb->protocol = eth_type_trans(skb, oai_nw_drv_dev[inst]);
// minus 1(short) instead of 2(bytes) because uint16_t*
p_ether_type = (uint16_t *)(skb_network_header(skb)-2);
ether_type = ntohs(*p_ether_type);
switch (ether_type) {
case ETH_P_ARP:
#ifdef OAI_DRV_DEBUG_RECEIVE
printk("[OAI_IP_DRV][%s] ether_type = ETH_P_ARP\n",__FUNCTION__);
#endif
//skb->pkt_type = PACKET_HOST;
skb->protocol = htons(ETH_P_ARP);
break;
default:
;
}
printk("[OAI_IP_DRV][%s] begin RB %d Inst %d Length %d bytes\n",__FUNCTION__,rb_id,inst,dlen);
printk("[OAI_IP_DRV][%s] Inst %d: receive unknown message (version=%d)\n",__FUNCTION__,inst,ipv->version);
}
++gpriv->stats.rx_packets;
gpriv->stats.rx_bytes += dlen;
#ifdef OAI_DRV_DEBUG_RECEIVE
printk("[OAI_IP_DRV][%s] sending packet of size %d to kernel\n",__FUNCTION__,skb->len);
for (i=0; i<skb->len; i++)
printk("%2x ",((unsigned char *)(skb->data))[i]);
printk("\n");
#endif //OAI_DRV_DEBUG_RECEIVE
netif_rx_ni(skb);
#ifdef OAI_DRV_DEBUG_RECEIVE
printk("[OAI_IP_DRV][%s] end\n",__FUNCTION__);
#endif
}
//---------------------------------------------------------------------------
// Delete the data
void oai_nw_drv_common_ip2wireless_drop(struct sk_buff *skb, int inst)
{
//---------------------------------------------------------------------------
struct oai_nw_drv_priv *priv=netdev_priv(oai_nw_drv_dev[inst]);
++priv->stats.tx_dropped;
}
//---------------------------------------------------------------------------
// Request the transfer of data (QoS SAP)
void oai_nw_drv_common_ip2wireless(struct sk_buff *skb, int inst)
{
//---------------------------------------------------------------------------
struct pdcp_data_req_header_s pdcph;
struct oai_nw_drv_priv *priv=netdev_priv(oai_nw_drv_dev[inst]);
#ifdef LOOPBACK_TEST
int i;
#endif
#ifdef OAI_DRV_DEBUG_SEND
int j;
#endif
unsigned int bytes_wrote;
// Start debug information
#ifdef OAI_DRV_DEBUG_SEND
printk("[OAI_IP_DRV][%s] inst %d begin \n",__FUNCTION__,inst);
#endif
if (skb==NULL) {
#ifdef OAI_DRV_DEBUG_SEND
printk("[OAI_IP_DRV][%s] input parameter skb is NULL \n",__FUNCTION__);
#endif
return;
}
pdcph.data_size = skb->len;
pdcph.rb_id = skb->mark;
pdcph.inst = inst;
pdcph.traffic_type = oai_nw_drv_find_traffic_type(skb);
bytes_wrote = oai_nw_drv_netlink_send((char *)&pdcph,OAI_NW_DRV_PDCPH_SIZE);
#ifdef OAI_DRV_DEBUG_SEND
printk("[OAI_IP_DRV][%s] Wrote %d bytes (header for %d byte skb) to PDCP RB %d via netlink\n",__FUNCTION__,
bytes_wrote,skb->len, pdcph.rb_id);
#endif
if (bytes_wrote != OAI_NW_DRV_PDCPH_SIZE) {
printk("[OAI_IP_DRV][%s] problem while writing PDCP's header (bytes wrote = %d to fifo %d)\n",__FUNCTION__,bytes_wrote,IP2PDCP_FIFO);
printk("rb_id %u, Wrote %u, Header Size %lu \n", pdcph.rb_id , bytes_wrote, OAI_NW_DRV_PDCPH_SIZE);
priv->stats.tx_dropped ++;
return;
}
bytes_wrote += oai_nw_drv_netlink_send((char *)skb->data,skb->len);
if (bytes_wrote != skb->len+OAI_NW_DRV_PDCPH_SIZE) {
printk("[OAI_IP_DRV][%s] Inst %d, RB_ID %u: problem while writing PDCP's data, bytes_wrote = %u, Data_len %u, PDCPH_SIZE %lu\n",
__FUNCTION__,
inst,
pdcph.rb_id,
bytes_wrote,
skb->len,
OAI_NW_DRV_PDCPH_SIZE); // congestion
priv->stats.tx_dropped ++;
return;
}
#ifdef OAI_DRV_DEBUG_SEND
printk("[OAI_IP_DRV][%s] Sending packet of size %d to PDCP traffic type %d\n",__FUNCTION__,skb->len, pdcph.traffic_type);
for (j=0; j<skb->len; j++)
printk("%2x ",((unsigned char *)(skb->data))[j]);
printk("\n");
#endif
priv->stats.tx_bytes += skb->len;
priv->stats.tx_packets ++;
#ifdef OAI_DRV_DEBUG_SEND
printk("[OAI_IP_DRV][%s] end \n",__FUNCTION__);
#endif
}
//---------------------------------------------------------------------------
void oai_nw_drv_common_wireless2ip(struct nlmsghdr *nlh)
{
//---------------------------------------------------------------------------
struct pdcp_data_ind_header_s *pdcph = (struct pdcp_data_ind_header_s *)NLMSG_DATA(nlh);
struct oai_nw_drv_priv *priv;
priv = netdev_priv(oai_nw_drv_dev[pdcph->inst]);
#ifdef OAI_DRV_DEBUG_RECEIVE
printk("[OAI_IP_DRV][%s] QOS receive from PDCP, size %d, rab %d, inst %d\n",__FUNCTION__,
pdcph->data_size,pdcph->rb_id,pdcph->inst);
#endif //OAI_DRV_DEBUG_RECEIVE
oai_nw_drv_common_class_wireless2ip(pdcph->data_size,
(unsigned char *)NLMSG_DATA(nlh) + OAI_NW_DRV_PDCPH_SIZE,
pdcph->inst,
pdcph->rb_id);
}

View File

@@ -1,174 +0,0 @@
/*
* 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
*/
#ifndef _OAI_NW_DRV_CST
#define _OAI_NW_DRV_CST
#define MAX_MEASURE_NB 5
#define OAI_NW_DRV_MAX_LENGTH 180
//Debug flags
//#define OAI_NW_DRV_DEBUG_DC
#define OAI_NW_DRV_DEBUG_SEND
#define OAI_NW_DRV_DEBUG_RECEIVE
//#define OAI_NW_DRV_DEBUG_CLASS
//#define OAI_NW_DRV_DEBUG_GC
//#define OAI_NW_DRV_DEBUG_DC_MEASURE
//#define OAI_NW_DRV_DEBUG_TIMER
//#define OAI_NW_DRV_DEBUG_DEVICE
//#define OAI_NW_DRV_DEBUG_INTERRUPT
//#define OAI_NW_DRV_DEBUG_TOOL
// Other flags
#define DEMO_3GSM
// General Constants
#define OAI_NW_DRV_MTU 1500
#define OAI_NW_DRV_TX_QUEUE_LEN 100
#define OAI_NW_DRV_ADDR_LEN 8
#define OAI_NW_DRV_INET6_ADDRSTRLEN 46
#define OAI_NW_DRV_INET_ADDRSTRLEN 16
#define OAI_NW_DRV_RESET_RX_FLAGS 0
#define OAI_NW_DRV_CX_MAX 32 //Identical to RRC constant
//#define OAI_NW_DRV_CX_MULTICAST_ALLNODE 2
#define OAI_NW_DRV_RETRY_LIMIT_DEFAULT 5
#define OAI_NW_DRV_MESSAGE_MAXLEN 5004
#define OAI_NW_DRV_SIG_SRB3 3
#define OAI_NW_DRV_SIG_SRB4 3 // not used yet
//peer-to-peer messages between NAS entities
#define OAI_NW_DRV_CMD_OPEN_RB 1
//#define OAI_NW_DRV_IID1_CONTROL 0x0
//#define OAI_NW_DRV_IID2_CONTROL __constant_htonl(0xffffffff)
//#define OAI_NW_DRV_STATE_IDLE 0
//#define OAI_NW_DRV_STATE_CONNECTED 1
//#define OAI_NW_DRV_STATE_ESTABLISHMENT_REQUEST 2
//#define OAI_NW_DRV_STATE_ESTABLISHMENT_FAILURE 3
//#define OAI_NW_DRV_STATE_RELEASE_FAILURE 4
#define OAI_NW_DRV_CX_RELEASE_UNDEF_CAUSE 1
// MT+RG NAS States
#define OAI_NW_DRV_IDLE 0x01
// Connection
#define OAI_NW_DRV_CX_FACH 0x06
#define OAI_NW_DRV_CX_DCH 0x0A
#define OAI_NW_DRV_CX_RECEIVED 0x10
#define OAI_NW_DRV_CX_CONNECTING 0x04
#define OAI_NW_DRV_CX_RELEASING 0x08
#define OAI_NW_DRV_CX_CONNECTING_FAILURE 0x14
#define OAI_NW_DRV_CX_RELEASING_FAILURE 0x18
// Radio Bearers
#define OAI_NW_DRV_RB_ESTABLISHING 0x24
#define OAI_NW_DRV_RB_RELEASING 0x28
#define OAI_NW_DRV_RB_DCH 0x2A
#define OAI_NW_DRV_TIMER_ESTABLISHMENT_DEFAULT 12
#define OAI_NW_DRV_TIMER_RELEASE_DEFAULT 2
#define OAI_NW_DRV_TIMER_IDLE UINT_MAX
#define OAI_NW_DRV_TIMER_TICK HZ
#define OAI_NW_DRV_PDCPH_SIZE sizeof(struct pdcp_data_req_header_s)
#define OAI_NW_DRV_IPV4_SIZE 20
#define OAI_NW_DRV_IPV6_SIZE 40
#define OAI_NW_DRV_DIRECTION_SEND 0
#define OAI_NW_DRV_DIRECTION_RECEIVE 1
#define OAI_NW_DRV_DIRECTION_FORWARD 2
// function number
#define OAI_NW_DRV_FCT_DEL_SEND 1
#define OAI_NW_DRV_FCT_QOS_SEND 2
#define OAI_NW_DRV_FCT_DC_SEND 3
#define OAI_NW_DRV_FCT_CTL_SEND 4
// type of IOCTL command
#define OAI_NW_DRV_IOCTL_RRM 0x89F0
// Error cause
#define OAI_NW_DRV_ERROR_ALREADYEXIST 1
#define OAI_NW_DRV_ERROR_NOMEMORY 3
#define OAI_NW_DRV_ERROR_NOTMT 9
#define OAI_NW_DRV_ERROR_NOTRG 10
#define OAI_NW_DRV_ERROR_NOTIDLE 11
#define OAI_NW_DRV_ERROR_NOTCONNECTED 12
#define OAI_NW_DRV_ERROR_NORB 14
#define OAI_NW_DRV_ERROR_NOTCORRECTVALUE 32
#define OAI_NW_DRV_ERROR_NOTCORRECTLCR 33
#define OAI_NW_DRV_ERROR_NOTCORRECTDIR 34
#define OAI_NW_DRV_ERROR_NOTCORRECTDSCP 35
#define OAI_NW_DRV_ERROR_NOTCORRECTVERSION 36
#define OAI_NW_DRV_ERROR_NOTCORRECTRABI 37
/**********************************************************/
/* Constants related with IP protocols */
/**********************************************************/
//#define OAI_NW_DRV_PORT_CONTROL __constant_htons(0xc45)
//#define OAI_NW_DRV_PORT_AUTHENTICATION __constant_htons(1811)
#define OAI_NW_DRV_TRAFFICCLASS_MASK __constant_htonl(0x0fc00000)
// Network control codepoint 111000 + IP version 6
#define OAI_NW_DRV_FLOWINFO_NCONTROL __constant_htonl(0x6e000000)
// network control codepoint 111000
#define OAI_NW_DRV_DSCP_NCONTROL 56 //0x38
// default codepoint 1000000
#define OAI_NW_DRV_DSCP_DEFAULT 64
#define OAI_NW_DRV_DSCP_MAX 193
#define OAI_NW_DRV_PROTOCOL_DEFAULT 0
#define OAI_NW_DRV_PROTOCOL_TCP IPPROTO_TCP
#define OAI_NW_DRV_PROTOCOL_UDP IPPROTO_UDP
#define OAI_NW_DRV_PROTOCOL_ICMP4 IPPROTO_ICMP
#define OAI_NW_DRV_PROTOCOL_ICMP6 IPPROTO_ICMPV6
//#warning "OAI_NW_DRV_PROTOCOL_ARP value 200 may collide with new defined values in kernel"
#define OAI_NW_DRV_PROTOCOL_ARP 200
#define OAI_NW_DRV_PORT_DEFAULT __constant_htons(65535)
#define OAI_NW_DRV_PORT_HTTP __constant_htons(80)
#define OAI_NW_DRV_IP_VERSION_ALL 0
#define OAI_NW_DRV_IP_VERSION_4 4
#define OAI_NW_DRV_IP_VERSION_6 6
#define OAI_NW_DRV_DEFAULT_IPV4_ADDR 0
#define OAI_NW_DRV_DEFAULT_IPV6_ADDR0 0
#define OAI_NW_DRV_DEFAULT_IPV6_ADDR1 0
#define OAI_NW_DRV_DEFAULT_IPV6_ADDR2 0
#define OAI_NW_DRV_DEFAULT_IPV6_ADDR3 0
#define OAI_NW_DRV_MPLS_VERSION_CODE 99
#define OAI_NW_DRV_NB_INSTANCES_MAX 8
#endif

View File

@@ -1,635 +0,0 @@
/*
* 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
*/
/*! \file device.c
* \brief Networking Device Driver for OpenAirInterface Ethernet
* \author navid.nikaein, Lionel Gauthier, raymond.knopp,
* \company Eurecom
* \email:navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr, raymond.knopp@eurecom.fr
*/
/*******************************************************************************/
#include "constant.h"
#include "local.h"
#include "proto_extern.h"
//#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/moduleparam.h>
#ifdef OAI_NW_DRIVER_TYPE_ETHERNET
#include <linux/if_ether.h>
#endif
#include <asm/io.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/delay.h>
#include <asm/unistd.h>
#include <linux/netdevice.h>
#ifdef OAI_NW_DRIVER_TYPE_ETHERNET
#include <linux/etherdevice.h>
#endif
struct net_device *oai_nw_drv_dev[OAI_NW_DRV_NB_INSTANCES_MAX];
#ifdef OAI_NW_DRIVER_USE_NETLINK
extern void oai_nw_drv_netlink_release(void);
extern int oai_nw_drv_netlink_init(void);
#endif
uint8_t NULL_IMEI[14]= {0x05, 0x04, 0x03, 0x01, 0x02 ,0x00, 0x00, 0x00, 0x05, 0x04, 0x03 ,0x00, 0x01, 0x08};
static unsigned char oai_nw_drv_IMEI[14];
static int m_arg=0;
static unsigned int oai_nw_drv_is_clusterhead=0;
//---------------------------------------------------------------------------
int oai_nw_drv_find_inst(struct net_device *dev)
{
//---------------------------------------------------------------------------
int i;
for (i=0; i<OAI_NW_DRV_NB_INSTANCES_MAX; i++)
if (oai_nw_drv_dev[i] == dev)
return(i);
return(-1);
}
//---------------------------------------------------------------------------
#ifndef OAI_NW_DRIVER_USE_NETLINK
void *oai_nw_drv_interrupt(void)
{
//---------------------------------------------------------------------------
uint8_t cxi;
// struct oai_nw_drv_priv *priv=netdev_priv(dev_id);
// unsigned int flags;
// priv->lock = SPIN_LOCK_UNLOCKED;
#ifdef OAI_DRV_DEBUG_INTERRUPT
printk("INTERRUPT - begin\n");
#endif
// spin_lock_irqsave(&priv->lock,flags);
cxi=0;
// mesh_GC_receive();
// mesh_DC_receive(naspriv->cx+cxi);
#ifndef OAI_NW_DRIVER_USE_NETLINK
oai_nw_drv_common_wireless2ip();
#endif
// spin_unlock_irqrestore(&priv->lock,flags);
#ifdef OAI_DRV_DEBUG_INTERRUPT
printk("INTERRUPT: end\n");
#endif
// return 0;
}
#endif //NETLINK
//---------------------------------------------------------------------------
void oai_nw_drv_timer(unsigned long data)
{
//---------------------------------------------------------------------------
struct oai_nw_drv_priv *priv=(struct oai_nw_drv_priv *)data;
spin_lock(&priv->lock);
(priv->timer).function=oai_nw_drv_timer;
(priv->timer).expires=jiffies+OAI_NW_DRV_TIMER_TICK;
(priv->timer).data=data;
add_timer(&priv->timer);
spin_unlock(&priv->lock);
return;
// add_timer(&gpriv->timer);
// spin_unlock(&gpriv->lock);
}
//---------------------------------------------------------------------------
// Called by ifconfig when the device is activated by ifconfig
int oai_nw_drv_open(struct net_device *dev)
{
//---------------------------------------------------------------------------
struct oai_nw_drv_priv *priv=netdev_priv(dev);
// Address has already been set at init
#ifndef OAI_NW_DRIVER_USE_NETLINK
if (pdcp_2_oai_nw_drv_irq==-EBUSY) {
printk("[OAI_IP_DRV][%s] : irq failure\n", __FUNCTION__);
return -EBUSY;
}
#endif //OAI_NW_DRIVER_USE_NETLINK
if(!netif_queue_stopped(dev))
netif_start_queue(dev);
else
netif_wake_queue(dev);
init_timer(&priv->timer);
(priv->timer).expires = jiffies+OAI_NW_DRV_TIMER_TICK;
(priv->timer).data = (unsigned long)priv;
(priv->timer).function = oai_nw_drv_timer;
//add_timer(&priv->timer);
printk("[OAI_IP_DRV][%s] name = %s\n", __FUNCTION__, dev->name);
return 0;
}
//---------------------------------------------------------------------------
// Called by ifconfig when the device is desactivated
int oai_nw_drv_stop(struct net_device *dev)
{
//---------------------------------------------------------------------------
struct oai_nw_drv_priv *priv = netdev_priv(dev);
printk("[OAI_IP_DRV][%s] Begin\n", __FUNCTION__);
del_timer(&(priv->timer));
netif_stop_queue(dev);
// MOD_DEC_USE_COUNT;
printk("[OAI_IP_DRV][%s] End\n", __FUNCTION__);
return 0;
}
//---------------------------------------------------------------------------
void oai_nw_drv_teardown(struct net_device *dev)
{
//---------------------------------------------------------------------------
struct oai_nw_drv_priv *priv;
int inst;
printk("[OAI_IP_DRV][%s] Begin\n", __FUNCTION__);
if (dev) {
priv = netdev_priv(dev);
inst = oai_nw_drv_find_inst(dev);
if ((inst<0) || (inst>=OAI_NW_DRV_NB_INSTANCES_MAX)) {
printk("[OAI_IP_DRV][%s] ERROR, couldn't find instance\n", __FUNCTION__);
return;
}
/*oai_nw_drv_class_flush_recv_classifier(priv);
for (cxi=0;cxi<OAI_NW_DRV_CX_MAX;cxi++) {
oai_nw_drv_common_flush_rb(priv->cx+cxi);
oai_nw_drv_class_flush_send_classifier(priv->cx+cxi);
}*/
printk("[OAI_IP_DRV][%s] End\n", __FUNCTION__);
} // check dev
else {
printk("[OAI_IP_DRV][%s] Device is null\n", __FUNCTION__);
}
}
//---------------------------------------------------------------------------
int oai_nw_drv_set_config(struct net_device *dev, struct ifmap *map)
{
//---------------------------------------------------------------------------
printk("[OAI_IP_DRV][%s] Begin\n", __FUNCTION__);
if (dev->flags & IFF_UP)
return -EBUSY;
if (map->base_addr != dev->base_addr) {
printk(KERN_WARNING "[OAI_IP_DRV][%s] Can't change I/O address\n", __FUNCTION__);
return -EOPNOTSUPP;
}
if (map->irq != dev->irq)
dev->irq = map->irq;
printk("[OAI_IP_DRV][%s] End\n", __FUNCTION__);
return 0;
}
//---------------------------------------------------------------------------
//
int oai_nw_drv_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
//---------------------------------------------------------------------------
int inst;
if (dev) {
inst = oai_nw_drv_find_inst(dev);
} else {
printk("[OAI_IP_DRV][%s] ERROR, device is null\n", __FUNCTION__);
return -1;
}
if ((inst>=0) && (inst<OAI_NW_DRV_NB_INSTANCES_MAX)) {
#ifdef OAI_DRV_OAI_DRV_DEBUG_DEVICE
printk("[OAI_IP_DRV][%s] inst %d, begin\n", __FUNCTION__,inst);
#endif
if (!skb) {
printk("[OAI_IP_DRV][%s] input parameter skb is NULL\n", __FUNCTION__);
return -1;
}
// End debug information
netif_stop_queue(dev);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
netif_trans_update(dev);
#else
dev->trans_start = jiffies;
#endif
#ifdef OAI_DRV_DEBUG_DEVICE
printk("[OAI_IP_DRV][%s] step 1\n", __FUNCTION__);
#endif
oai_nw_drv_common_ip2wireless(skb,inst);
#ifdef OAI_DRV_DEBUG_DEVICE
printk("[OAI_IP_DRV][%s] step 2\n", __FUNCTION__);
#endif
dev_kfree_skb(skb);
#ifdef OAI_DRV_DEBUG_DEVICE
printk("[OAI_IP_DRV][%s] step 3\n", __FUNCTION__);
#endif
netif_wake_queue(dev);
#ifdef OAI_DRV_DEBUG_DEVICE
printk("[OAI_IP_DRV][%s] end\n", __FUNCTION__);
#endif
} else {
printk("[OAI_IP_DRV][%s] ERROR, couldn't find instance\n", __FUNCTION__);
return(-1);
}
return 0;
}
//---------------------------------------------------------------------------
struct net_device_stats *oai_nw_drv_get_stats(struct net_device *dev)
{
//---------------------------------------------------------------------------
// return &((struct oai_nw_drv_priv *)dev->priv)->stats;
struct oai_nw_drv_priv *priv = netdev_priv(dev);
//printk("[OAI_IP_DRV][%s]\n", __FUNCTION__);
return &priv->stats;
}
//---------------------------------------------------------------------------
int oai_nw_drv_set_mac_address(struct net_device *dev, void *mac)
{
//---------------------------------------------------------------------------
struct sockaddr *addr = mac;
printk("[OAI_IP_DRV][%s] CHANGE MAC ADDRESS\n", __FUNCTION__);
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
return 0;
}
//---------------------------------------------------------------------------
int oai_nw_drv_change_mtu(struct net_device *dev, int mtu)
{
//---------------------------------------------------------------------------
printk("[OAI_IP_DRV][%s] CHANGE MTU %d bytes\n", __FUNCTION__, mtu);
if ((mtu<50) || (mtu>1500))
return -EINVAL;
dev->mtu = mtu;
return 0;
}
//---------------------------------------------------------------------------
void oai_nw_drv_change_rx_flags(struct net_device *dev, int flags)
{
//---------------------------------------------------------------------------
struct oai_nw_drv_priv *priv = netdev_priv(dev);
printk("[OAI_IP_DRV][%s] CHANGE RX FLAGS %08X\n", __FUNCTION__, flags);
priv->rx_flags ^= flags;
}
//---------------------------------------------------------------------------
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
void oai_nw_drv_tx_timeout(struct net_device *dev, unsigned int txqueue)
#else
void oai_nw_drv_tx_timeout(struct net_device *dev)
#endif
{
//---------------------------------------------------------------------------
// Transmitter timeout, serious problems.
struct oai_nw_drv_priv *priv = netdev_priv(dev);
printk("[OAI_IP_DRV][%s] begin\n", __FUNCTION__);
// (struct oai_nw_drv_priv *)(dev->priv)->stats.tx_errors++;
(priv->stats).tx_errors++;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
netif_trans_update(dev);
#else
dev->trans_start = jiffies;
#endif
netif_wake_queue(dev);
printk("[OAI_IP_DRV][%s] transmit timed out %s\n", __FUNCTION__,dev->name);
}
static const struct net_device_ops nasmesh_netdev_ops = {
.ndo_open = oai_nw_drv_open,
.ndo_stop = oai_nw_drv_stop,
.ndo_start_xmit = oai_nw_drv_hard_start_xmit,
.ndo_validate_addr = NULL,
.ndo_get_stats = oai_nw_drv_get_stats,
.ndo_set_mac_address = oai_nw_drv_set_mac_address,
.ndo_set_config = oai_nw_drv_set_config,
.ndo_do_ioctl = oai_nw_drv_CTL_ioctl,
.ndo_change_mtu = oai_nw_drv_change_mtu,
.ndo_tx_timeout = oai_nw_drv_tx_timeout,
.ndo_change_rx_flags = oai_nw_drv_change_rx_flags,
};
/*.ndo_set_multicast_list = NULL,*/
//---------------------------------------------------------------------------
// Initialisation of the network device
void oai_nw_drv_init(struct net_device *dev)
{
//---------------------------------------------------------------------------
uint8_t cxi;
struct oai_nw_drv_priv *priv;
int index;
if (dev) {
priv = netdev_priv(dev);
memset(priv, 0, sizeof(struct oai_nw_drv_priv));
#ifndef OAI_NW_DRIVER_TYPE_ETHERNET
dev->type = ARPHRD_EURECOM_LTE;
dev->features = NETIF_F_NO_CSUM;
dev->hard_header_len = 0;
dev->addr_len = ETH_ALEN; // 6
dev->flags = IFF_BROADCAST | IFF_MULTICAST | IFF_NOARP;
dev->tx_queue_len = NAS_TX_QUEUE_LEN;
dev->mtu = NAS_MTU;
#endif
// Can be one of the following enum defined in include/linux/netdevice.h:
// enum netdev_state_t {
// __LINK_STATE_START,
// __LINK_STATE_PRESENT,
// __LINK_STATE_NOCARRIER,
// __LINK_STATE_LINKWATCH_PENDING,
// __LINK_STATE_DORMANT,
// };
set_bit(__LINK_STATE_PRESENT, &dev->state);
//
dev->netdev_ops = &nasmesh_netdev_ops;
#ifdef OAI_NW_DRIVER_TYPE_ETHERNET
printk("[OAI_IP_DRV][%s] Driver type ETHERNET\n", __FUNCTION__);
// Memo: linux-source-3.2.0/net/ethernet/eth.c:
//334 void ether_setup(struct net_device *dev)
//335 {
//336 dev->header_ops = &eth_header_ops;
//337 dev->type = ARPHRD_ETHER;
//338 dev->hard_header_len = ETH_HLEN;
//339 dev->mtu = ETH_DATA_LEN;
//340 dev->addr_len = ETH_ALEN;
//341 dev->tx_queue_len = 1000; /* Ethernet wants good queues */
//342 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
//343 dev->priv_flags |= IFF_TX_SKB_SHARING;
//344
//345 memset(dev->broadcast, 0xFF, ETH_ALEN);
//346 }
ether_setup(dev);
#endif
//
// Initialize private structure
priv->rx_flags = OAI_NW_DRV_RESET_RX_FLAGS;
priv->sap[OAI_NW_DRV_RAB_INPUT_SAPI] = PDCP2IP_FIFO;//QOS_DEVICE_CONVERSATIONAL_INPUT;
priv->sap[OAI_NW_DRV_RAB_OUTPUT_SAPI] = IP2PDCP_FIFO;//QOS_DEVICE_STREAMING_INPUT;
// priv->retry_limit=RETRY_LIMIT_DEFAULT;
// priv->timer_establishment=TIMER_ESTABLISHMENT_DEFAULT;
// priv->timer_release=TIMER_RELEASE_DEFAULT;
/*for (dscpi=0; dscpi<OAI_NW_DRV_DSCP_MAX; ++dscpi) {
priv->rclassifier[dscpi]=NULL;
}
priv->nrclassifier=0;*/
//
for (cxi=0; cxi<OAI_NW_DRV_CX_MAX; cxi++) {
#ifdef OAI_DRV_DEBUG_DEVICE
printk("[OAI_IP_DRV][%s] init classifiers, state and timer for MT %u\n", __FUNCTION__, cxi);
#endif
// priv->cx[cxi].sap[NAS_DC_INPUT_SAPI] = RRC_DEVICE_DC_INPUT0;
// priv->cx[cxi].sap[NAS_DC_OUTPUT_SAPI] = RRC_DEVICE_DC_OUTPUT0;
priv->cx[cxi].state = OAI_NW_DRV_IDLE;
priv->cx[cxi].countimer = OAI_NW_DRV_TIMER_IDLE;
priv->cx[cxi].retry = 0;
priv->cx[cxi].lcr = cxi;
/*priv->cx[cxi].rb = NULL;
priv->cx[cxi].num_rb = 0;
// initialisation of the classifier
for (dscpi=0; dscpi<65; ++dscpi) {
priv->cx[cxi].sclassifier[dscpi] = NULL;
priv->cx[cxi].fclassifier[dscpi] = NULL;
}
priv->cx[cxi].nsclassifier=0;
priv->cx[cxi].nfclassifier=0;
*/
// initialisation of the IP address
oai_nw_drv_TOOL_eNB_imei2iid(oai_nw_drv_IMEI, (uint8_t *)priv->cx[cxi].iid6, dev->addr_len);
priv->cx[cxi].iid4=0;
//
}
spin_lock_init(&priv->lock);
//this requires kernel patch for OAI driver: typically for RF/hard realtime emu experimentation
#define ADDRCONF
#ifdef ADDRCONF
#ifdef OAI_NW_DRIVER_USE_NETLINK
oai_nw_drv_TOOL_eNB_imei2iid(oai_nw_drv_IMEI, dev->dev_addr, dev->addr_len);// IMEI to device address (for stateless autoconfiguration address)
oai_nw_drv_TOOL_eNB_imei2iid(oai_nw_drv_IMEI, (uint8_t *)priv->cx[0].iid6, dev->addr_len);
#else
oai_nw_drv_TOOL_imei2iid(oai_nw_drv_IMEI, dev->dev_addr);// IMEI to device address (for stateless autoconfiguration address)
oai_nw_drv_TOOL_imei2iid(oai_nw_drv_IMEI, (uint8_t *)priv->cx[0].iid6);
#endif
// this is more appropriate for user space soft realtime emulation
#else
// LG: strange
for (index = 0; index < dev->addr_len; index++) {
dev->dev_addr[index] = 16*oai_nw_drv_IMEI[index]+oai_nw_drv_IMEI[index+1]);
}
memcpy((uint8_t *)priv->cx[0].iid6,&oai_nw_drv_IMEI[0],dev->addr_len);
printk("INIT: init IMEI to IID\n");
#endif
printk("[OAI_IP_DRV][%s] Setting HW addr to : ", __FUNCTION__);
for (index = 0; index < dev->addr_len; index++) {
printk("%02X", dev->dev_addr[index]);
}
printk("\n[OAI_IP_DRV][%s] Setting priv->cx to : ", __FUNCTION__);
for (index = 0; index < 8; index++) {
printk("%02X", ((uint8_t *)(priv->cx[0].iid6))[index]);
}
printk("\n");
printk("[OAI_IP_DRV][%s] INIT: end\n", __FUNCTION__);
return;
} else {
printk("[OAI_IP_DRV][%s] ERROR, Device is NULL!!\n", __FUNCTION__);
return;
}
}
//---------------------------------------------------------------------------
int init_module (void)
{
//---------------------------------------------------------------------------
int err,inst, index;
struct oai_nw_drv_priv *priv;
char devicename[100];
// Initialize parameters shared with RRC
printk("[OAI_IP_DRV][%s] Starting NASMESH, number of IMEI parameters %d, IMEI ", __FUNCTION__, m_arg);
for (index = 0; index < m_arg; index++) {
printk("%02X", oai_nw_drv_IMEI[index]);
}
printk("\n");
#ifndef OAI_NW_DRIVER_USE_NETLINK
if (pdcp_2_oai_nw_drv_irq == -EBUSY || pdcp_2_oai_nw_drv_irq == -EINVAL) {
printk("[OAI_IP_DRV][%s] No interrupt resource available\n", __FUNCTION__);
return -EBUSY;
} else
printk("[OAI_IP_DRV][%s] Interrupt %d\n", __FUNCTION__, pdcp_2_oai_nw_drv_irq);
#endif //NETLINK
for (inst=0; inst<OAI_NW_DRV_NB_INSTANCES_MAX; inst++) {
printk("[OAI_IP_DRV][%s] begin init instance %d\n", __FUNCTION__,inst);
sprintf(devicename,"oai%d",inst);
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
oai_nw_drv_dev[inst] = alloc_netdev(sizeof(struct oai_nw_drv_priv),devicename, oai_nw_drv_init);
#else
oai_nw_drv_dev[inst] = alloc_netdev(sizeof(struct oai_nw_drv_priv),devicename, NET_NAME_PREDICTABLE, oai_nw_drv_init);
#endif
//netif_stop_queue(oai_nw_drv_dev[inst]);
if (oai_nw_drv_dev[inst] == NULL) {
printk("[OAI_IP_DRV][%s][INST %02d] alloc_netdev FAILED\n", __FUNCTION__,inst);
} else {
priv = netdev_priv(oai_nw_drv_dev[inst]);
if (oai_nw_drv_dev[inst]) {
oai_nw_drv_IMEI[9] += 1;
if (oai_nw_drv_IMEI[9] > 0x0F) {
oai_nw_drv_IMEI[8] = oai_nw_drv_IMEI[9] >> 4;
oai_nw_drv_IMEI[9] = oai_nw_drv_IMEI[9] & 0x0F;
}
}
// linux/net/core/dev.c line 4767
err= register_netdev(oai_nw_drv_dev[inst]);
if (err) {
printk("[OAI_IP_DRV][%s] (inst %d): error %i registering device %s\n", __FUNCTION__, inst,err, oai_nw_drv_dev[inst]->name);
} else {
printk("[OAI_IP_DRV][%s] registering device %s, ifindex = %d\n\n", __FUNCTION__,oai_nw_drv_dev[inst]->name, oai_nw_drv_dev[inst]->ifindex);
}
}
}
#ifdef OAI_NW_DRIVER_USE_NETLINK
printk("[OAI_IP_DRV][%s] NETLINK INIT\n", __FUNCTION__);
if ((err=oai_nw_drv_netlink_init()) == -1)
printk("[OAI_IP_DRV][%s] NETLINK failed\n", __FUNCTION__);
#endif //NETLINK
return err;
}
//---------------------------------------------------------------------------
void cleanup_module(void)
{
//---------------------------------------------------------------------------
int inst;
printk("[OAI_IP_DRV][CLEANUP]nasmesh_cleanup_module: begin\n");
#ifndef OAI_NW_DRIVER_USE_NETLINK
if (pdcp_2_oai_nw_drv_irq!=-EBUSY) {
pdcp_2_oai_nw_drv_irq=0;
// Start IRQ linux
//free_irq(priv->irq, NULL);
// End IRQ linux
}
#else // NETLINK
#endif //NETLINK
for (inst=0; inst<OAI_NW_DRV_NB_INSTANCES_MAX; inst++) {
#ifdef OAI_DRV_DEBUG_DEVICE
printk("nasmesh_cleanup_module: unregister and free net device instance %d\n",inst);
#endif
if (oai_nw_drv_dev[inst]) {
unregister_netdev(oai_nw_drv_dev[inst]);
oai_nw_drv_teardown(oai_nw_drv_dev[inst]);
free_netdev(oai_nw_drv_dev[inst]);
}
}
#ifdef OAI_NW_DRIVER_USE_NETLINK
oai_nw_drv_netlink_release();
#endif //OAI_NW_DRIVER_USE_NETLINK
printk("nasmesh_cleanup_module: end\n");
}
#define DRV_NAME "NASMESH"
#define DRV_VERSION "3.0.2"DRV_NAME
#define DRV_DESCRIPTION "OPENAIR MESH Device Driver"
#define DRV_COPYRIGHT "-Copyright(c) GNU GPL Eurecom 2009"
#define DRV_AUTHOR "Raymond Knopp, and Navid Nikaein: <firstname.name@eurecom.fr>"DRV_COPYRIGHT
module_param_array_named(oai_nw_drv_IMEI,oai_nw_drv_IMEI,byte,&m_arg,0);
//module_param_array(oai_nw_drv_IMEI,byte,&m_arg,0444);
MODULE_PARM_DESC(oai_nw_drv_IMEI,"The IMEI Hardware address (64-bit, decimal nibbles)");
//module_param(oai_nw_drv_is_clusterhead,uint,0444);
module_param_named(oai_nw_drv_is_clusterhead,oai_nw_drv_is_clusterhead,uint,0444);
MODULE_PARM_DESC(oai_nw_drv_is_clusterhead,"The Clusterhead Indicator");
//MODULE_AUTHOR(DRV_AUTHOR);
//MODULE_DESCRIPTION(DRV_DESCRIPTION);
//MODULE_LICENSE("GPL");
//MODULE_VERSION(DRV_VERSION);

View File

@@ -1,129 +0,0 @@
/*
* 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
*/
#include "local.h"
#include "ioctl.h"
#include "proto_extern.h"
#include <asm/uaccess.h>
#include <asm/checksum.h>
#include <asm/uaccess.h>
#define NIP6ADDR(addr) \
ntohs((addr)->s6_addr16[0]), \
ntohs((addr)->s6_addr16[1]), \
ntohs((addr)->s6_addr16[2]), \
ntohs((addr)->s6_addr16[3]), \
ntohs((addr)->s6_addr16[4]), \
ntohs((addr)->s6_addr16[5]), \
ntohs((addr)->s6_addr16[6]), \
ntohs((addr)->s6_addr16[7])
uint8_t g_msgrep[OAI_NW_DRV_LIST_CLASS_MAX*sizeof(struct oai_nw_drv_msg_class_list_reply)+1];
// Statistic
//---------------------------------------------------------------------------
void oai_nw_drv_set_msg_statistic_reply(struct oai_nw_drv_msg_statistic_reply *msgrep,
struct oai_nw_drv_priv *priv)
{
//---------------------------------------------------------------------------
msgrep->rx_packets=priv->stats.rx_packets;
msgrep->tx_packets=priv->stats.tx_packets;
msgrep->rx_bytes=priv->stats.rx_bytes;
msgrep->tx_bytes=priv->stats.tx_bytes;
msgrep->rx_errors=priv->stats.rx_errors;
msgrep->tx_errors=priv->stats.tx_errors;
msgrep->rx_dropped=priv->stats.rx_dropped;
msgrep->tx_dropped=priv->stats.tx_dropped;
}
//---------------------------------------------------------------------------
int oai_nw_drv_ioCTL_statistic_request(struct oai_nw_drv_ioctl *gifr,
struct oai_nw_drv_priv *priv)
{
//---------------------------------------------------------------------------
struct oai_nw_drv_msg_statistic_reply msgrep;
printk("NAS_IOCTL_STATISTIC: stat requested\n");
oai_nw_drv_set_msg_statistic_reply(&msgrep,priv);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("NAS_IOCTL_STATISTIC: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// IMEI
// Messages for IMEI transfer
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// IOCTL command
//---------------------------------------------------------------------------
int oai_nw_drv_CTL_ioctl(struct net_device *dev,
struct ifreq *ifr,
int cmd)
{
//---------------------------------------------------------------------------
struct oai_nw_drv_ioctl *gifr;
struct oai_nw_drv_priv *priv=netdev_priv(dev);
int r;
// printk("NAS_CTL_IOCTL: begin ioctl for instance %d\n",find_inst(dev));
switch(cmd) {
case OAI_NW_DRV_IOCTL_RRM:
gifr=(struct oai_nw_drv_ioctl *)ifr;
switch(gifr->type) {
case OAI_NW_DRV_MSG_STATISTIC_REQUEST:
r=oai_nw_drv_ioCTL_statistic_request(gifr,priv);
break;
default:
// printk("NAS_IOCTL_RRM: unkwon request type, type=%x\n", gifr->type);
r=-EFAULT;
}
break;
default:
// printk("NAS_CTL_IOCTL: Unknown ioctl command, cmd=%x\n", cmd);
r=-EFAULT;
}
// printk("NAS_CTL_IOCTL: end\n");
return r;
}
//---------------------------------------------------------------------------
void oai_nw_drv_CTL_send(struct sk_buff *skb, int inst)
{
//---------------------------------------------------------------------------
printk("NAS_CTL_SEND - void \n");
}

View File

@@ -1,256 +0,0 @@
/*
* 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
*/
/***************************************************************************
ioctl.h - description
-------------------
copyright : (C) 2002 by Eurecom
email : michelle.wetterwald@eurecom.fr
yan.moret@eurecom.fr
knopp@eurecom.fr
***************************************************************************
***************************************************************************/
#ifndef OAI_IOCTL_H
#define OAI_IOCTL_H
#include <asm/byteorder.h>
#include <asm/types.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/if.h>
#include "sap.h"
//#include <linux/ipv6.h>
#define OAI_NW_DRV_MSG_MAXLEN 1100/// change???
// type of CTL message
#define OAI_NW_DRV_MSG_STATISTIC_REQUEST 1
#define OAI_NW_DRV_MSG_STATISTIC_REPLY 2
#define OAI_NW_DRV_MSG_ECHO_REQUEST 3
#define OAI_NW_DRV_MSG_ECHO_REPLY 4
#define OAI_NW_DRV_MSG_CX_ESTABLISHMENT_REQUEST 5
#define OAI_NW_DRV_MSG_CX_ESTABLISHMENT_REPLY 6
#define OAI_NW_DRV_MSG_CX_RELEASE_REQUEST 7
#define OAI_NW_DRV_MSG_CX_RELEASE_REPLY 8
#define OAI_NW_DRV_MSG_CX_LIST_REQUEST 9
#define OAI_NW_DRV_MSG_CX_LIST_REPLY 10
#define OAI_NW_DRV_MSG_RB_ESTABLISHMENT_REQUEST 11
#define OAI_NW_DRV_MSG_RB_ESTABLISHMENT_REPLY 12
#define OAI_NW_DRV_MSG_RB_RELEASE_REQUEST 13
#define OAI_NW_DRV_MSG_RB_RELEASE_REPLY 14
#define OAI_NW_DRV_MSG_RB_LIST_REQUEST 15
#define OAI_NW_DRV_MSG_RB_LIST_REPLY 16
#define OAI_NW_DRV_MSG_CLASS_ADD_REQUEST 17
#define OAI_NW_DRV_MSG_CLASS_ADD_REPLY 18
#define OAI_NW_DRV_MSG_CLASS_DEL_REQUEST 19
#define OAI_NW_DRV_MSG_CLASS_DEL_REPLY 20
#define OAI_NW_DRV_MSG_CLASS_LIST_REQUEST 21
#define OAI_NW_DRV_MSG_CLASS_LIST_REPLY 22
#define OAI_NW_DRV_MSG_MEAS_REQUEST 23
#define OAI_NW_DRV_MSG_MEAS_REPLY 24
#define OAI_NW_DRV_MSG_IMEI_REQUEST 25
#define OAI_NW_DRV_MSG_IMEI_REPLY 26
// Max number of entry of a message list
#define OAI_NW_DRV_LIST_CX_MAX 32
#define OAI_NW_DRV_LIST_RB_MAX 32
#define OAI_NW_DRV_LIST_CLASS_MAX 32
typedef unsigned short oai_nw_drv_MsgType_t;
struct oai_nw_drv_ioctl {
char name[IFNAMSIZ];
oai_nw_drv_MsgType_t type;
char *msg;
};
struct oai_nw_drv_msg_statistic_reply {
unsigned int rx_packets;
unsigned int tx_packets;
unsigned int rx_bytes;
unsigned int tx_bytes;
unsigned int rx_errors;
unsigned int tx_errors;
unsigned int rx_dropped;
unsigned int tx_dropped;
};
struct oai_nw_drv_msg_cx_list_reply {
OaiNwDrvLocalConnectionRef_t lcr; // Local Connection reference
unsigned char state;
OaiNwDrvCellID_t cellid; // cell identification
unsigned int iid6[2]; // IPv6 interface identification
unsigned char iid4; // IPv4 interface identification
unsigned short num_rb;
unsigned short nsclassifier;
};
struct oai_nw_drv_msg_cx_establishment_reply {
int status;
};
struct oai_nw_drv_msg_cx_establishment_request {
OaiNwDrvLocalConnectionRef_t lcr; // Local Connection reference
OaiNwDrvCellID_t cellid; // Cell identification
};
struct oai_nw_drv_msg_cx_release_reply {
int status;
};
struct oai_nw_drv_msg_cx_release_request {
OaiNwDrvLocalConnectionRef_t lcr; // Local Connection reference
};
struct oai_nw_drv_msg_rb_list_reply {
OaiNwDrvRadioBearerId_t rab_id;
OaiNwDrvSapId_t sapi;
OaiNwDrvQoSTrafficClass_t qos;
unsigned char state;
};
struct oai_nw_drv_msg_rb_list_request {
OaiNwDrvLocalConnectionRef_t lcr; // Local Connection reference
};
struct oai_nw_drv_msg_rb_establishment_reply {
int status;
};
struct oai_nw_drv_msg_rb_establishment_request {
OaiNwDrvLocalConnectionRef_t lcr; // Local Connection reference
OaiNwDrvRadioBearerId_t rab_id;
OaiNwDrvQoSTrafficClass_t qos;
};
struct oai_nw_drv_msg_rb_release_reply {
int status;
};
struct oai_nw_drv_msg_rb_release_request {
OaiNwDrvLocalConnectionRef_t lcr; // Local Connection reference
OaiNwDrvRadioBearerId_t rab_id;
};
/*
struct saddr {
struct in6_addr ipv6;
unsigned int ipv4;
};
struct daddr {
struct in6_addr ipv6;
unsigned int ipv4;
unsigned int mpls_label;
};
*/
struct oai_nw_drv_msg_class_add_request {
OaiNwDrvLocalConnectionRef_t lcr; // Local Connection reference
OaiNwDrvRadioBearerId_t rab_id;
OaiNwDrvRadioBearerId_t rab_id_rx;
unsigned char dir; // direction (send or receive, forward)
unsigned char dscp; // codepoint
unsigned char fct;
unsigned short classref;
unsigned char version;
//struct daddr daddr;
//struct saddr saddr;
unsigned char splen; // prefix length
union {
struct in6_addr ipv6;
// begin navid
//in_addr_t ipv4;
unsigned int ipv4;
//end navid
unsigned int mpls_label;
} daddr; // IP destination address
union {
struct in6_addr ipv6;
// begin navid
//in_addr_t ipv4;
unsigned int ipv4;
//end navid
} saddr; // IP source address
unsigned char dplen; // prefix length
unsigned char protocol; //!< transport layer protocol type (ANY,TCP,UDP,ICMPv4,ICMPv6)
unsigned char protocol_message_type; //!< transport layer protocol message (ROUTER_ADV, ROUTER_SOLL, etc.)
unsigned short sport; //!< source port
unsigned short dport; //!< destination port
};
struct oai_nw_drv_msg_class_add_reply {
int status;
};
struct oai_nw_drv_msg_class_del_request {
OaiNwDrvLocalConnectionRef_t lcr; // Local Connection reference
unsigned char dir; // direction (send or receive)
unsigned char dscp; // codepoint
unsigned short classref;
};
struct oai_nw_drv_msg_class_del_reply {
int status;
};
#define oai_nw_drv_msg_class_list_reply oai_nw_drv_msg_class_add_request
struct oai_nw_drv_msg_class_list_request {
OaiNwDrvLocalConnectionRef_t lcr; // Local Connection reference
unsigned char dir;
unsigned char dscp;
};
// Messages for Measurement transfer - MW 01/04/2005
typedef unsigned int nioctlProviderId_t;
typedef unsigned short nioctlSignalLoss_t;
typedef struct nioctlMeasures {
OaiNwDrvCellID_t cell_id;
OaiNwDrvSigLevel_t level;
nioctlProviderId_t provider_id;
} nioctlMeasures_t;
struct oai_nw_drv_msg_measure_request {
OaiNwDrvNumRGsMeas_t num_cells;
OaiNwDrvCellID_t cellid[OAI_NW_DRV_MAX_MEASURE_NB]; // Cell identification
unsigned short num_providers;
nioctlProviderId_t provider_id[OAI_NW_DRV_MAX_MEASURE_NB]; // Provider identification
};
struct oai_nw_drv_msg_measure_reply {
OaiNwDrvNumRGsMeas_t num_cells;
nioctlMeasures_t measures[OAI_NW_DRV_MAX_MEASURE_NB];
nioctlSignalLoss_t signal_lost_flag;
};
// Messages for Measurement transfer - MW 01/04/2005
typedef unsigned int nioctlL2Id_t[2];
struct oai_nw_drv_msg_l2id_reply {
nioctlL2Id_t l2id;
};
#endif

View File

@@ -1,132 +0,0 @@
/*
* 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
*/
/***************************************************************************
local.h - description
-------------------
copyright : (C) 2002 by Eurecom
email :navid.nikaein@eurecom.fr
lionel.gauthier@eurecom.fr
knopp@eurecom.fr
***************************************************************************
***************************************************************************/
#ifndef OAI_LOCAL_H
#define OAI_LOCAL_H
#include <linux/if_arp.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/ipv6.h>
#include <linux/ip.h>
#include <linux/sysctl.h>
#include <linux/timer.h>
#include <linux/unistd.h>
#include <asm/param.h>
//#include <sys/sysctl.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
#include <linux/in.h>
#include <net/ndisc.h>
#define PDCP2IP_FIFO 21
#define IP2PDCP_FIFO 22
#include "constant.h"
#include "common/platform_types.h"
#include "sap.h"
struct cx_entity {
int sap[OAI_NW_DRV_SAPI_CX_MAX];
uint8_t state; // state of the connection
OaiNwDrvLocalConnectionRef_t lcr; // Local connection reference
OaiNwDrvCellID_t cellid; // cell identification
uint32_t countimer; // timeout's counter
uint8_t retry; // number of retransmission
uint32_t iid6[2]; // IPv6 interface identification
uint8_t iid4; // IPv4 interface identification
int lastRRCprimitive;
//measures
int req_prov_id [OAI_NW_DRV_MAX_MEASURE_NB];
int num_measures;
int meas_cell_id[OAI_NW_DRV_MAX_MEASURE_NB];
int meas_level [OAI_NW_DRV_MAX_MEASURE_NB];
int provider_id [OAI_NW_DRV_MAX_MEASURE_NB];
};
struct oai_nw_drv_priv {
int irq;
int rx_flags;
struct timer_list timer;
spinlock_t lock;
struct net_device_stats stats;
uint8_t retry_limit;
uint32_t timer_establishment;
uint32_t timer_release;
struct cx_entity cx[OAI_NW_DRV_CX_MAX];
//struct classifier_entity *rclassifier[OAI_NW_DRV_DSCP_MAX]; // receive classifier
uint16_t nrclassifier;
int sap[OAI_NW_DRV_SAPI_MAX];
struct sock *nl_sk;
uint8_t nlmsg[OAI_NW_DRV_PRIMITIVE_MAX_LENGTH+sizeof(struct nlmsghdr)];
uint8_t xbuffer[OAI_NW_DRV_PRIMITIVE_MAX_LENGTH]; // transmition buffer
uint8_t rbuffer[OAI_NW_DRV_PRIMITIVE_MAX_LENGTH]; // reception buffer
};
struct ipversion {
#if defined(__LITTLE_ENDIAN_BITFIELD)
uint8_t reserved:4,
version:4;
#else
uint8_t version:4,
reserved:4;
#endif
};
typedef struct pdcp_data_req_header_s {
rb_id_t rb_id;
sdu_size_t data_size;
signed int inst;
ip_traffic_type_t traffic_type;
} pdcp_data_req_header_t;
typedef struct pdcp_data_ind_header_s {
rb_id_t rb_id;
sdu_size_t data_size;
signed int inst;
ip_traffic_type_t dummy_traffic_type;
} pdcp_data_ind_header_t;
extern struct net_device *oai_nw_drv_dev[OAI_NW_DRV_NB_INSTANCES_MAX];
extern uint8_t OAI_NW_DRV_NULL_IMEI[14];
#endif

View File

@@ -1,199 +0,0 @@
/*
* 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
*/
/*! \file netlink.c
* \brief establish a netlink
* \author Navid Nikaein, Lionel Gauthier, and Raymond knopp
* \company Eurecom
* \email:navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr, knopp@eurecom.fr
*/
#include <linux/version.h>
//#include <linux/config.h>
#include <linux/socket.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netlink.h>
#include <net/sock.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
#include "local.h"
#include "proto_extern.h"
//#define NETLINK_DEBUG 1
#define OAI_IP_DRIVER_NETLINK_ID 31
#define NL_DEST_PID 1
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
struct netlink_kernel_cfg oai_netlink_cfg;
#endif
static struct sock *nas_nl_sk = NULL;
static int exit_netlink_thread=0;
static int nas_netlink_rx_thread(void *);
static DEFINE_MUTEX(nasmesh_mutex);
static inline void nasmesh_lock(void)
{
mutex_lock(&nasmesh_mutex);
}
static inline void nasmesh_unlock(void)
{
mutex_unlock(&nasmesh_mutex);
}
// This can also be implemented using thread to get the data from PDCP without blocking.
static void nas_nl_data_ready (struct sk_buff *skb)
{
// wake_up_interruptible(skb->sk->sk_sleep);
//nasmesh_lock();
//netlink_rcv_skb(skb, &my_rcv_msg);// my_rcv_msg is the call back func>
//nasmesh_unlock();
struct nlmsghdr *nlh = NULL;
if (skb) {
#ifdef NETLINK_DEBUG
printk("[OAI_IP_DRV][NETLINK] Received socket from PDCP\n");
#endif //NETLINK_DEBUG
nlh = (struct nlmsghdr *)skb->data;
oai_nw_drv_common_wireless2ip(nlh);
//kfree_skb(skb); // not required,
}
}
int oai_nw_drv_netlink_init(void)
{
printk("[OAI_IP_DRV][NETLINK] Running init ...\n");
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
oai_netlink_cfg.groups = 0;
oai_netlink_cfg.input = nas_nl_data_ready;
oai_netlink_cfg.cb_mutex = &nasmesh_mutex;
oai_netlink_cfg.bind = NULL;
nas_nl_sk = netlink_kernel_create(
&init_net,
OAI_IP_DRIVER_NETLINK_ID,
# if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
THIS_MODULE,
# endif
&oai_netlink_cfg);
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */
nas_nl_sk = netlink_kernel_create(
&init_net,
OAI_IP_DRIVER_NETLINK_ID,
0,
nas_nl_data_ready,
&nasmesh_mutex, // NULL
THIS_MODULE);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */
if (nas_nl_sk == NULL) {
printk("[OAI_IP_DRV][NETLINK] netlink_kernel_create failed \n");
return(-1);
}
return(0);
}
void oai_nw_drv_netlink_release(void)
{
exit_netlink_thread=1;
printk("[OAI_IP_DRV][NETLINK] Releasing netlink socket\n");
if(nas_nl_sk) {
netlink_kernel_release(nas_nl_sk); //or skb->sk
}
// printk("[OAI_IP_DRV][NETLINK] Removing netlink_rx_thread\n");
//kthread_stop(netlink_rx_thread);
}
int oai_nw_drv_netlink_send(unsigned char *data,unsigned int len)
{
struct sk_buff *nl_skb = alloc_skb(NLMSG_SPACE(len),GFP_ATOMIC);
struct nlmsghdr *nlh = (struct nlmsghdr *)nl_skb->data;
int status;
// printk("[OAI_IP_DRV][NETLINK] Sending %d bytes (%d)\n",len,NLMSG_SPACE(len));
skb_put(nl_skb, NLMSG_SPACE(len));
memcpy(NLMSG_DATA(nlh),data,len);
nlh->nlmsg_len = NLMSG_SPACE(len);
nlh->nlmsg_pid = 0; /* from kernel */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
NETLINK_CB(nl_skb).portid = 0;
#else
NETLINK_CB(nl_skb).pid = 0;
#endif
#ifdef NETLINK_DEBUG
printk("[OAI_IP_DRV][NETLINK] In nas_netlink_send, nl_skb %p, nl_sk %x, nlh %p, nlh->nlmsg_len %d\n",nl_skb,nas_nl_sk,nlh,nlh->nlmsg_len);
#endif //DEBUG_NETLINK
if (nas_nl_sk) {
// nasmesh_lock();
status = netlink_unicast(nas_nl_sk, nl_skb, NL_DEST_PID, MSG_DONTWAIT);
// mutex_unlock(&nasmesh_mutex);
if (status < 0) {
printk("[OAI_IP_DRV][NETLINK] SEND status is %d\n",status);
return(0);
} else {
#ifdef NETLINK_DEBUG
printk("[OAI_IP_DRV][NETLINK] SEND status is %d\n",status);
#endif
return len;
}
} else {
printk("[OAI_IP_DRV][SEND] socket is NULL\n");
return(0);
}
}

View File

@@ -1,173 +0,0 @@
/*
* 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
*/
/***************************************************************************
proto_extern.h - description
-------------------
copyright : (C) 2002 by Eurecom
email : michelle.wetterwald@eurecom.fr
yan.moret@eurecom.fr
knopp@eurecom.fr
***************************************************************************
***************************************************************************/
#ifndef __NETWORK_DRIVER_LITE_PROTO_EXTERN__H__
#define __NETWORK_DRIVER_LITE_PROTO_EXTERN__H__
#include <linux/if_arp.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/ipv6.h>
#include <linux/ip.h>
#include <linux/sysctl.h>
#include <linux/timer.h>
#include <asm/param.h>
//#include <sys/sysctl.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
#include <linux/in.h>
#include <net/ndisc.h>
#include "local.h"
// device.c
/** @defgroup _oai_nw_drv_impl_ OAI Network Device for RRC Lite
* @ingroup _ref_implementation_
* @{
\fn int oai_nw_drv_find_inst(struct net_device *dev)
\brief This function determines the instance id for a particular device pointer.
@param dev Pointer to net_device structure
*/
int oai_nw_drv_find_inst(struct net_device *dev);
// common.c
/**
\fn void oai_nw_drv_common_class_wireless2ip(unsigned short dlen, void* pdcp_sdu,int inst,OaiNwDrvRadioBearerId_t rb_id)
\brief Receive classified LTE packet, build skbuff struct with it and deliver it to the OS network layer.
@param dlen Length of SDU in bytes
@param pdcp_sdu Pointer to received SDU
@param inst Instance number
@param rb_id Radio Bearer Id
*/
void oai_nw_drv_common_class_wireless2ip(unsigned short dlen,
void *pdcp_sdu,
int inst,
OaiNwDrvRadioBearerId_t rb_id);
/**
\fn void oai_nw_drv_common_ip2wireless(struct sk_buff *skb, int inst)
\brief Request the transfer of data (QoS SAP)
@param skb pointer to socket buffer
@param inst device instance
*/
void oai_nw_drv_common_ip2wireless(struct sk_buff *skb, int inst);
/**
\fn void oai_nw_drv_common_ip2wireless_drop(struct sk_buff *skb, int inst)
\brief Drop the IP packet comming from the OS network layer.
@param skb pointer to socket buffer
@param inst device instance
*/
void oai_nw_drv_common_ip2wireless_drop(struct sk_buff *skb, int inst);
#ifndef OAI_NW_DRIVER_USE_NETLINK
/**
\fn void oai_nw_drv_common_wireless2ip()
\brief Retrieve PDU from PDCP through RT-fifos for delivery to the IP stack.
*/
void oai_nw_drv_common_wireless2ip(void);
#else
/**
\fn void oai_nw_drv_common_wireless2ip(struct nlmsghdr *nlh)
\brief Retrieve PDU from PDCP through netlink sockets for delivery to the IP stack.
*/
void oai_nw_drv_common_wireless2ip(struct nlmsghdr *nlh);
#endif //OAI_NW_DRIVER_USE_NETLINK
#ifdef OAI_NW_DRIVER_USE_NETLINK
/**
\fn int oai_nw_drv_netlink_send(unsigned char *data,unsigned int len)
\brief Request the transfer of data by PDCP via netlink socket
@param data pointer to SDU
@param len length of SDU in bytes
@returns Numeber of bytes transfered by netlink socket
*/
int oai_nw_drv_netlink_send(unsigned char *data,unsigned int len);
/**
\fn void oai_nw_drv_COMMON_QOS_receive(struct nlmsghdr *nlh)
\brief Request a PDU from PDCP
@param nlh pointer to netlink message header
*/
void oai_nw_drv_COMMON_QOS_receive(struct nlmsghdr *nlh);
#endif //OAI_NW_DRIVER_USE_NETLINK
// iocontrol.c
void oai_nw_drv_CTL_send(struct sk_buff *skb, int inst);
int oai_nw_drv_CTL_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
// classifier.c
/**
\brief Find the IP traffic type (UNICAST, MULTICAST, BROADCAST) of the IP packet attached to sk_buff.
*/
ip_traffic_type_t oai_nw_drv_find_traffic_type(struct sk_buff *skb);
// tool.c
void oai_nw_drv_TOOL_imei2iid(unsigned char *imei, unsigned char *iid);
void oai_nw_drv_TOOL_eNB_imei2iid(unsigned char *imei, unsigned char *iid, unsigned char len);
unsigned char oai_nw_drv_TOOL_get_dscp6(struct ipv6hdr *iph);
unsigned char oai_nw_drv_TOOL_get_dscp4(struct iphdr *iph);
unsigned char *oai_nw_drv_TOOL_get_protocol6(struct ipv6hdr *iph, unsigned char *protocol);
unsigned char *oai_nw_drv_TOOL_get_protocol4(struct iphdr *iph, unsigned char *protocol);
char *oai_nw_drv_TOOL_get_udpmsg(struct udphdr *udph);
unsigned short oai_nw_drv_TOOL_udpcksum(struct in6_addr *saddr, struct in6_addr *daddr, unsigned char proto, unsigned int udplen, void *data);
int oai_nw_drv_TOOL_network6(struct in6_addr *addr, struct in6_addr *prefix, unsigned char plen);
int oai_nw_drv_TOOL_network4(unsigned int *addr, unsigned int *prefix, unsigned char plen);
void print_TOOL_pk_icmp6(struct icmp6hdr *icmph);
void print_TOOL_pk_all(struct sk_buff *skb);
void print_TOOL_pk_ipv6(struct ipv6hdr *iph);
void print_TOOL_state(unsigned char state);
void oai_nw_drv_tool_print_buffer(char * buffer,int length);
#ifdef OAI_NW_DRIVER_USE_NETLINK
// netlink.c
void oai_nw_drv_netlink_release(void);
int oai_nw_drv_netlink_init(void);
#endif
/** @} */
#endif

View File

@@ -1,40 +0,0 @@
/*
* 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
*/
#ifndef OAI_SAP_H
#define OAI_SAP_H
typedef unsigned short OaiNwDrvRadioBearerId_t;
typedef unsigned int OaiNwDrvSapId_t; // Id of the QoS SAP to use
typedef unsigned short OaiNwDrvQoSTrafficClass_t; // QoS traffic class requested
typedef unsigned int OaiNwDrvLocalConnectionRef_t; // local identifier
typedef unsigned short OaiNwDrvCellID_t; // ID of the cell for connection
typedef unsigned short OaiNwDrvNumRGsMeas_t; // number of RGs that could be measured
typedef unsigned int OaiNwDrvSigLevel_t; // Signal level measured
#define OAI_NW_DRV_SAPI_CX_MAX 2
#define OAI_NW_DRV_MAX_MEASURE_NB 5
#define OAI_NW_DRV_PRIMITIVE_MAX_LENGTH 180 // maximum length of a NAS primitive
#define OAI_NW_DRV_SAPI_MAX 4
#define OAI_NW_DRV_RAB_INPUT_SAPI 2
#define OAI_NW_DRV_RAB_OUTPUT_SAPI 3
#define OAI_NW_DRV_MAX_RABS 8 * 64 //NB_RAB_MAX * MAX_MOBILES_PER_RG //27 // = MAXURAB
#define OAI_NW_DRV_LIST_RB_MAX 32
#endif

View File

@@ -1,747 +0,0 @@
/*
* 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
*/
#include "local.h"
#include "proto_extern.h"
//#include <linux/in.h>
//#include <net/ndisc.h>
//#include <linux/icmpv6.h>
//#include <linux/icmp.h>
//#include <linux/udp.h>
//#include <linux/tcp.h>
//#define OAI_NW_DRV_DEBUG_TOOL 1
//---------------------------------------------------------------------------
uint8_t oai_nw_drv_TOOL_get_dscp6(struct ipv6hdr *iph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_GET_DSCP6 - begin \n");
#endif
if (iph==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_GET_DSCP6 - input parameter iph is NULL \n");
#endif
return 0;
}
// End debug information
return (ntohl(((*(__u32 *)iph)&OAI_NW_DRV_TRAFFICCLASS_MASK)))>>22;
//return ntohs(*(const __be16 *)iph) >> 4; // see linux/dsfield.h
}
//---------------------------------------------------------------------------
uint8_t oai_nw_drv_TOOL_get_dscp4(struct iphdr *iph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_GET_DSCP4 - begin \n");
#endif
if (iph==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_GET_DSCP4 - input parameter iph is NULL \n");
#endif
return 0;
}
// End debug information
return (iph->tos);
}
//---------------------------------------------------------------------------
int oai_nw_drv_TOOL_network6(struct in6_addr *addr, struct in6_addr *prefix, uint8_t plen)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_NETWORK6 - begin \n");
#endif
if (addr==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_NETWORK6 - input parameter addr is NULL \n");
#endif
return 0;
}
if (prefix==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_NETWORK6 - input parameter prefix is NULL \n");
#endif
return 0;
}
// End debug information
switch(plen/32) {
case 0:
return (((addr->s6_addr32[0]>>(32-plen))<<(32-plen))==prefix->s6_addr[0]);
case 1:
return ((addr->s6_addr32[0]==prefix->s6_addr[0])&&
(((addr->s6_addr32[1]>>(64-plen))<<(64-plen))==prefix->s6_addr[1]));
case 2:
return ((addr->s6_addr32[0]==prefix->s6_addr[0])&&
(addr->s6_addr32[1]==prefix->s6_addr[1])&&
(((addr->s6_addr32[2]>>(96-plen))<<(96-plen))==prefix->s6_addr[2]));
case 3:
return ((addr->s6_addr32[0]==prefix->s6_addr[0])&&
(addr->s6_addr32[1]==prefix->s6_addr[1])&&
(addr->s6_addr32[2]==prefix->s6_addr[2])&&
(((addr->s6_addr32[3]>>(128-plen))<<(128-plen))==prefix->s6_addr[3]));
default:
return ((addr->s6_addr32[0]==prefix->s6_addr[0])&&
(addr->s6_addr32[1]==prefix->s6_addr[1])&&
(addr->s6_addr32[2]==prefix->s6_addr[2])&&
(addr->s6_addr32[3]==prefix->s6_addr[3]));
}
}
//---------------------------------------------------------------------------
int oai_nw_drv_TOOL_network4(uint32_t *addr, uint32_t *prefix, uint8_t plen)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_NETWORK4 - begin \n");
#endif
if (addr==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_NETWORK4 - input parameter addr is NULL \n");
#endif
return 0;
}
if (prefix==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_NETWORK4 - input parameter prefix is NULL \n");
#endif
return 0;
}
// End debug information
if (plen>=32)
return (*addr==*prefix);
else
return (((*addr>>(32-plen))<<(32-plen))==*prefix);
}
//---------------------------------------------------------------------------
//struct udphdr *oai_nw_drv_TOOL_get_udp6(struct ipv6hdr *iph){
//---------------------------------------------------------------------------
// return (struct udphdr *)((char *)iph+OAI_NW_DRV_IPV6_SIZE); // to modify
//}
//---------------------------------------------------------------------------
uint8_t *oai_nw_drv_TOOL_get_protocol6(struct ipv6hdr *iph, uint8_t *protocol)
{
//---------------------------------------------------------------------------
uint16_t size;
// Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_GET_PROTOCOL6 - begin \n");
#endif
if (iph==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_GET_PROTOCOL6 - input parameter iph is NULL \n");
#endif
return NULL;
}
if (protocol==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_GET_PROTOCOL6 - input parameter protocol is NULL \n");
#endif
return NULL;
}
// End debug information
*protocol=iph->nexthdr;
size=OAI_NW_DRV_IPV6_SIZE;
while (1) {
switch(*protocol) {
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_ICMPV6:
return (uint8_t *)((uint8_t *)iph+size);
case IPPROTO_HOPOPTS:
case IPPROTO_ROUTING:
case IPPROTO_DSTOPTS:
*protocol=((uint8_t *)iph+size)[0];
size+=((uint8_t *)iph+size)[1]*8+8;
break;
case IPPROTO_FRAGMENT:
*protocol=((uint8_t *)iph+size)[0];
size+=((uint8_t *)iph+size)[1]+8;
break;
case IPPROTO_NONE:
case IPPROTO_AH:
case IPPROTO_ESP:
default:
return NULL;
}
}
}
//---------------------------------------------------------------------------
uint8_t *oai_nw_drv_TOOL_get_protocol4(struct iphdr *iph, uint8_t *protocol)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_GET_PROTOCOL4 - begin \n");
#endif
if (iph==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_GET_PROTOCOL4 - input parameter iph is NULL \n");
#endif
return NULL;
}
if (protocol==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_GET_PROTOCOL4 - input parameter protocol is NULL \n");
#endif
return NULL;
}
// End debug information
*protocol=iph->protocol;
switch(*protocol) {
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_ICMP:
return (uint8_t *)((uint8_t *)iph+iph->tot_len);
default:
return NULL;
}
}
//---------------------------------------------------------------------------
// Convert the IMEI to iid
void oai_nw_drv_TOOL_imei2iid(uint8_t *imei, uint8_t *iid)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_IMEI2IID - begin \n");
#endif
if (imei==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_IMEI2IID - input parameter imei is NULL \n");
#endif
return;
}
if (iid==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_IMEI2IID - input parameter iid is NULL \n");
#endif
return;
}
// End debug information
memset(iid, 0, OAI_NW_DRV_ADDR_LEN);
iid[0] = 0x03;
iid[1] = 16*imei[0]+imei[1];
iid[2] = 16*imei[2]+imei[3];
iid[3] = 16*imei[4]+imei[5];
iid[4] = 16*imei[6]+imei[7];
iid[5] = 16*imei[8]+imei[9];
iid[6] = 16*imei[10]+imei[11];
iid[7] = 16*imei[12]+imei[13];
}
//---------------------------------------------------------------------------
// Convert the IMEI to iid
void oai_nw_drv_TOOL_eNB_imei2iid(unsigned char *imei, unsigned char *iid, unsigned char len)
{
//---------------------------------------------------------------------------
unsigned int index;
// Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_eNB_IMEI2IID - begin \n");
#endif
if (imei==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_eNB_IMEI2IID - input parameter imei is NULL \n");
#endif
return;
}
if (iid==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_eNB_IMEI2IID - input parameter iid is NULL \n");
#endif
return;
}
// End debug information
memset(iid, 0, len);
iid[0] = 0x00; // to be compatible between link local and global
// len -1 because of insertion of 0 above
for (index = 0; index < (len-1); index++) {
iid[index+1] = 16*imei[index*2]+imei[index*2+1];
}
}
//struct udphdr *oai_nw_drv_TOOL_get_udp4(struct iphdr *iph)
//{
// return (struct udphdr *)((char *)iph+OAI_NW_DRV_IPV4_SIZE); // to modify
//}
//---------------------------------------------------------------------------
char *oai_nw_drv_TOOL_get_udpmsg(struct udphdr *udph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_GET_UDPMSG - begin \n");
#endif
if (udph==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_GET_UDPMSG - input parameter udph is NULL \n");
#endif
return NULL;
}
// End debug information
return ((char *)udph+sizeof(struct udphdr));
}
//---------------------------------------------------------------------------
// Compute the UDP checksum (the data size must be odd)
uint16_t oai_nw_drv_TOOL_udpcksum(struct in6_addr *saddr, struct in6_addr *daddr, uint8_t proto, uint32_t udplen, void *data)
{
//---------------------------------------------------------------------------
uint32_t i;
uint16_t *data16;
uint32_t csum=0;
// Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_UDPCKSUM - begin \n");
#endif
if (saddr==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_UDPCKSUM - input parameter saddr is NULL \n");
#endif
return 0;
}
if (daddr==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_UDPCKSUM - input parameter daddr is NULL \n");
#endif
return 0;
}
if (data==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_UDPCKSUM - input parameter data is NULL \n");
#endif
return 0;
}
// End debug information
data16=data;
for (i=0; i<8; ++i) {
csum+=ntohs(saddr->s6_addr16[i]);
if (csum>0xffff)
csum-=0xffff;
}
for (i=0; i<8; ++i) {
csum+=ntohs(daddr->s6_addr16[i]);
if (csum>0xffff)
csum-=0xffff;
}
csum+=(udplen>>16); // udplen checksum
if (csum>0xffff)
csum -= 0xffff;
csum+=udplen & 0xffff;
if (csum>0xffff)
csum -= 0xffff;
csum+=proto; // protocol checksum
if (csum>0xffff)
csum-=0xffff;
for (i = 0; 2*i < udplen; i++) {
csum+=ntohs(data16[i]);
if (csum>0xffff)
csum-=0xffff;
}
return htons((uint16_t)(~csum)&0xffff);
}
//---------------------------------------------------------------------------
void print_TOOL_pk_udp(struct udphdr *udph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("PRINT_TOOL_PK_UDP - begin \n");
#endif
if (udph==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_PK_UDP - input parameter udph is NULL \n");
#endif
return;
}
// End debug information
if (udph!=NULL) {
printk("UDP:\t source = %u, dest = %u, len = %u, check = %x\n", ntohs(udph->source), ntohs(udph->dest), ntohs(udph->len), udph->check);
}
}
//---------------------------------------------------------------------------
void print_TOOL_pk_tcp(struct tcphdr *tcph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("PRINT_TOOL_PK_TDP - begin \n");
#endif
if (tcph==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_PK_TDP - input parameter tcph is NULL \n");
#endif
return;
}
// End debug information
if (tcph!=NULL) {
printk("TCP:\t source = %u, dest = %u\n", tcph->source, tcph->dest);
}
}
//---------------------------------------------------------------------------
void print_TOOL_pk_icmp6(struct icmp6hdr *icmph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("PRINT_TOOL_PK_ICMP6 - begin \n");
#endif
if (icmph==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_PK_ICMP6 - input parameter icmph is NULL \n");
#endif
return;
}
// End debug information
if (icmph!=NULL) {
printk("ICMPv6:\t type= %d, code = %d\n", icmph->icmp6_type, icmph->icmp6_code);
switch(icmph->icmp6_type) {
case ICMPV6_DEST_UNREACH:
printk("Destination unreachable\n");
break;
case ICMPV6_PKT_TOOBIG:
printk("Packet too big\n");
break;
case ICMPV6_TIME_EXCEED:
printk("Time exceeded\n");
break;
case ICMPV6_PARAMPROB:
printk("Parameter problem\n");
break;
case ICMPV6_ECHO_REQUEST:
printk("Echo request\n");
break;
case ICMPV6_ECHO_REPLY:
printk("Echo reply\n");
break;
case ICMPV6_MGM_QUERY:
printk("Multicast listener query\n");
break;
case ICMPV6_MGM_REPORT:
printk("Multicast listener report\n");
break;
case ICMPV6_MGM_REDUCTION:
printk("Multicast listener done\n");
break;
case NDISC_ROUTER_SOLICITATION:
printk("Router solicitation\n");
break;
case NDISC_ROUTER_ADVERTISEMENT:
printk("Router advertisment\n");
break;
case NDISC_NEIGHBOUR_SOLICITATION:
printk("Neighbour solicitation\n");
break;
case NDISC_NEIGHBOUR_ADVERTISEMENT:
printk("Neighbour advertisment\n");
break;
case NDISC_REDIRECT:
printk("redirect message\n");
break;
}
}
}
//---------------------------------------------------------------------------
void print_TOOL_pk_ipv6(struct ipv6hdr *iph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("PRINT_TOOL_PK_IPv6 - begin \n");
#endif
if (iph==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_PK_IPv6 - input parameter iph is NULL \n");
#endif
return;
}
// End debug information
if (iph!=NULL) {
// char addr[OAI_NW_DRV_INET6_ADDRSTRLEN];
printk("IP:\t version = %u, priority = %u, payload_len = %u\n", iph->version, iph->priority, ntohs(iph->payload_len));
printk("\t fl0 = %u, fl1 = %u, fl2 = %u\n",iph->flow_lbl[0],iph->flow_lbl[1],iph->flow_lbl[2]);
printk("\t next header = %u, hop_limit = %u\n", iph->nexthdr, iph->hop_limit);
// inet_ntop(AF_INET6, (void *)(&iph->saddr), addr, OAI_NW_DRV_INET6_ADDRSTRLEN);
// printk("\t saddr = %s",addr);
// inet_ntop(AF_INET6, (void *)(&iph->daddr), addr, OAI_NW_DRV_INET6_ADDRSTRLEN);
// printk(", daddr = %s\n",addr);
switch(iph->nexthdr) {
case IPPROTO_UDP:
print_TOOL_pk_udp((struct udphdr *)((char *)iph+sizeof(struct ipv6hdr)));
break;
case IPPROTO_TCP:
print_TOOL_pk_tcp((struct tcphdr *)((char *)iph+sizeof(struct ipv6hdr)));
break;
case IPPROTO_ICMPV6:
print_TOOL_pk_icmp6((struct icmp6hdr *)((char *)iph+sizeof(struct ipv6hdr)));
break;
case IPPROTO_IPV6:
print_TOOL_pk_ipv6((struct ipv6hdr *)((char *)iph+sizeof(struct ipv6hdr)));
break;
default:
printk("Unknown upper layer\n");
}
}
}
//---------------------------------------------------------------------------
void print_TOOL_pk_ipv4(struct iphdr *iph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("PRINT_TOOL_PK_IPv4 - begin \n");
#endif
if (iph==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_PK_IPv4 - input parameter iph is NULL \n");
#endif
return;
}
// End debug information
if (iph!=NULL) {
// char addr[OAI_NW_DRV_INET_ADDRSTRLEN];
printk("IP:\t version = %u, IP length = %u\n", iph->version, iph->ihl);
// inet_ntop(AF_INET, (void *)(&iph->saddr), addr, OAI_NW_DRV_INET_ADDRSTRLEN);
// printk("\t saddr = %s", addr);
// inet_ntop(AF_INET, (void *)(&iph->saddr), addr, OAI_NW_DRV_INET_ADDRSTRLEN);
// printk("\t saddr = %s", addr);
}
}
//---------------------------------------------------------------------------
void print_TOOL_pk_all(struct sk_buff *skb)
{
//---------------------------------------------------------------------------
printk("Skb:\t %u, len = %u\n", (unsigned int)skb, skb->len);
//navid: need to calculate the current used space: fixme?
printk("Skb:\t available buf space = %u \n", skb->truesize);
switch (ntohs(skb->protocol)) {
case ETH_P_IPV6:
print_TOOL_pk_ipv6((struct ipv6hdr *)skb->network_header);
break;
case ETH_P_IP:
print_TOOL_pk_ipv4((struct iphdr *)skb->network_header);
break;
}
}
//---------------------------------------------------------------------------
/*int isdigit(char c)
{
switch(c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return 1;
default:
return 0;
}
}*/
/*int oai_nw_drv_TOOL_inet_pton4(char *src, uint32_t *dst)
{
uint32_t val;
int n;
uint8_t c;
uint32_t parts[4];
c = *src;
val=0;
n=0
for (;;)
{
for (;;)
{
if (isdigit(c))
{
val = (val * 10) + c - '0';
c = *++src;
}
else
break;
}
if (c == '.')
{
if (n>4)
return -1;
parts[n]=val;
c = *++src;
++n;
}
else
break;
}
if ((c != '\0')||(n!=3))
return (0);
if ((parts[0] | parts[1] | parts[2] | val) > 256)
return (0);
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
if (dst)
dst = htonl(val);
return (1);
}*/
//-----------------------------------------------------------------------------
// Print the content of a buffer in hexadecimal
void oai_nw_drv_tool_print_buffer(char * buffer,int length)
{
//-----------------------------------------------------------------------------
int i;
// Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_PRINT_BUFFER - begin \n");
#endif
if (buffer==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
printk("OAI_NW_DRV_TOOL_PRINT_BUFFER - input parameter buffer is NULL \n");
#endif
return;
}
// End debug information
printk("\nBuffer content: ");
for (i=0; i<length; i++)
printk("-%hx-",buffer[i]);
printk(",\t length %d\n", length);
}

View File

@@ -1,12 +0,0 @@
CC = gcc
NAS_DIR = ..
rb_tool: rb_tool.c
$(CC) rb_tool.c -o rb_tool -I../ -g -ggdb
all: rb_tool
clean:
rm -f rb_tool

View File

@@ -1,413 +0,0 @@
/*
* 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
*/
/***************************************************************************
rb_tool.c - User-space utility for driving NASMESH IOCTL interface
-------------------
copyright : (C) 2008 by Eurecom
email : raymond.knopp@eurecom.fr and navid.nikaein@eurecom.fr
***************************************************************************
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <ctype.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//
//#include "ral_cdma_variables.h"
//#include "ral_cdma_proto.h"
#include "rrc_nas_primitives.h"
#include "ioctl.h"
#include "constant.h"
//#include "nasmt_constant.h"
//#include "nasmt_iocontrol.h"
// Global variables
//int sd_graal;
int fd;
//char myIPAddr[16]; // local IP Address
//int meas_counter;
//struct ralu_priv ru_priv;
//struct ralu_priv *ralupriv;
//ioctl
char dummy_buffer[1024];
struct nas_ioctl gifr;
//int wait_start_nas;
/*
//---------------------------------------------------------------------------
int NAS_RALconnect(void)
//---------------------------------------------------------------------------
{
struct sockaddr_un remote;
int len,s;
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("NAS_RALconnect - socket");
exit(1);
}
//
printf("Trying to connect to NAS ...\n");
remote.sun_family = AF_UNIX;
strcpy(remote.sun_path, SOCKET_RAL_TD_CDMA_NAME);
len = strlen(remote.sun_path) + sizeof(remote.sun_family);
while (wait_start_graal){
if (connect(s, (struct sockaddr *)&remote, len) == -1) {
perror("NAS_RALconnect - waiting for connection - ");
// exit(1);
wait_start_graal = 1;
sleep(5);
} else {
wait_start_graal =0;
printf("RAL connected to NAS.\n");
}
}
return s;
}
*/
//---------------------------------------------------------------------------
void IAL_NAS_ioctl_init(int inst)
//---------------------------------------------------------------------------
{
struct nas_msg_statistic_reply *msgrep;
int err;
sprintf(gifr.name, "oai%d",inst);
// Get an UDP IPv6 socket ??
fd=socket(AF_INET6, SOCK_DGRAM, 0);
if (fd<0) {
printf("Error opening socket\n");
exit(1);
}
sprintf(gifr.name, "oai%d",inst);
gifr.type = NAS_MSG_STATISTIC_REQUEST;
memset ((void *)dummy_buffer,0,800);
gifr.msg= &(dummy_buffer[0]);
msgrep=(struct nas_msg_statistic_reply *)(gifr.msg);
printf("ioctl :Statistics requested\n");
err=ioctl(fd, NAS_IOCTL_RRM, &gifr);
if (err<0) {
printf("IOCTL error, err=%d\n",err);
}
printf("tx_packets = %u, rx_packets = %u\n", msgrep->tx_packets, msgrep->rx_packets);
printf("tx_bytes = %u, rx_bytes = %u\n", msgrep->tx_bytes, msgrep->rx_bytes);
printf("tx_errors = %u, rx_errors = %u\n", msgrep->tx_errors, msgrep->rx_errors);
printf("tx_dropped = %u, rx_dropped = %u\n", msgrep->tx_dropped, msgrep->rx_dropped);
}
#define ADD_RB 0
#define DEL_RB 1
//---------------------------------------------------------------------------
int main(int argc,char **argv)
//---------------------------------------------------------------------------
{
int err = 0;
int c = 0;
int action=0,rbset=0,cxset=0,instset=0,saddr_ipv4set=0,saddr_ipv6set=0,daddr_ipv4set=0,daddr_ipv6set=0,dscpset=0,mpls_outlabelset=0,mpls_inlabelset=0;
char rb[100],cx[100],dscp[100],inst[100],mpls_outgoinglabel[100],mpls_incominglabel[100];
struct nas_msg_rb_establishment_request *msgreq = NULL;
struct nas_msg_class_add_request *msgreq_class = NULL;
in_addr_t saddr_ipv4 = 0,daddr_ipv4 = 0;
struct in6_addr saddr_ipv6,daddr_ipv6;
unsigned int mpls_outlabel=0,mpls_inlabel=0;
char addr_str[46];
// scan options
rb[0] = '\0';
cx[0] = '\0';
dscp[0] = '\0';
mpls_incominglabel[0] = '\0';
mpls_outgoinglabel[0] = '\0';
while ((c = getopt (argc, argv, "adr:i:c:l:m:s:t:x:y:z:")) != -1)
switch (c) {
case 'a':
action = ADD_RB;
break;
case 'd':
action = DEL_RB;
break;
case 'r':
strcpy(rb,optarg);
rbset = 1;
break;
case 'i':
strcpy(inst,optarg);
instset = 1;
break;
case 'c':
strcpy(cx,optarg);
cxset = 1;
break;
case 'l':
strcpy(mpls_outgoinglabel,optarg);
mpls_outlabelset=1;
break;
case 'm':
strcpy(mpls_incominglabel,optarg);
mpls_inlabelset=1;
break;
case 's': {
struct in_addr a;
inet_aton(optarg,&a);
saddr_ipv4 = a.s_addr;
saddr_ipv4set = 1;
break;
}
case 't': {
struct in_addr a;
inet_aton(optarg,&a);
daddr_ipv4 = a.s_addr;
daddr_ipv4set = 1;
break;
}
case 'x':
printf("IPv6: %s\n",optarg);
inet_pton(AF_INET6,optarg,(void *)&saddr_ipv6);
saddr_ipv6set = 1;
break;
case 'y':
inet_pton(AF_INET6,optarg,(void *)&daddr_ipv6);
daddr_ipv6set = 1;
break;
case 'z':
dscpset=1;
strcpy(dscp,optarg);
break;
case '?':
if (isprint (optopt))
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf (stderr,
"Unknown option character `\\x%x'.\n",
optopt);
return 1;
default:
abort ();
}
printf ("action = %d, rb = %s,cx = %s\n", action, rb, cx);
if (rbset==0) {
printf("ERROR: Specify a RAB id!!\n");
exit(-1);
}
if (cxset==0) {
printf("ERROR: Specify an LCR !!\n");
exit(-1);
}
if (instset==0) {
printf("ERROR: Specify an interface !!\n");
exit(-1);
}
if ((mpls_outlabelset == 0) && (saddr_ipv4set==0) && (saddr_ipv6set==0)) {
printf("ERROR: Specify a source IP address\n");
exit(-1);
}
if ((mpls_outlabelset == 0) && (daddr_ipv4set==0) && (daddr_ipv6set==0)) {
printf("ERROR: Specify a destination IP address\n");
exit(-1);
}
if ((mpls_outlabelset == 1) && (mpls_inlabelset == 0)) {
printf("ERROR: Specify an incoming MPLS label\n");
exit(-1);
}
if ((mpls_inlabelset == 1) && (mpls_outlabelset == 0)) {
printf("ERROR: Specify an outgoing MPLS label\n");
exit(-1);
}
IAL_NAS_ioctl_init(atoi(inst));
msgreq = (struct nas_msg_rb_establishment_request *)(gifr.msg);
msgreq->rab_id = atoi(rb);
msgreq->lcr = atoi(cx);
msgreq->qos = 0;
if (action == ADD_RB) {
gifr.type = NAS_MSG_RB_ESTABLISHMENT_REQUEST;
err=ioctl(fd, NAS_IOCTL_RRM, &gifr);
if (err == -1) perror("ioctl");
if (saddr_ipv4set == 1) {
msgreq_class = (struct nas_msg_class_add_request *)(gifr.msg);
msgreq_class->rab_id = atoi(rb);
msgreq_class->lcr = atoi(cx);
msgreq_class->version = 4;
msgreq_class->classref = 0 + (msgreq_class->lcr<<3);
msgreq_class->dir = NAS_DIRECTION_SEND;
msgreq_class->fct = NAS_FCT_QOS_SEND;
msgreq_class->saddr.ipv4 = saddr_ipv4;
msgreq_class->daddr.ipv4 = daddr_ipv4;
// TO BE FIXED WHEN WE CAN SPECIFY A PROTOCOL-based rule
msgreq_class->protocol = NAS_PROTOCOL_DEFAULT;
if (dscpset==0)
msgreq_class->dscp=0;
else
msgreq_class->dscp=atoi(dscp);
gifr.type = NAS_MSG_CLASS_ADD_REQUEST;
err=ioctl(fd, NAS_IOCTL_RRM, &gifr);
if (err == -1) perror("ioctl");
msgreq_class->rab_id = atoi(rb);
msgreq_class->lcr = atoi(cx);
msgreq_class->classref = 1+(msgreq_class->lcr<<3);
msgreq_class->dir = NAS_DIRECTION_RECEIVE;
msgreq_class->daddr.ipv4 = saddr_ipv4;
msgreq_class->saddr.ipv4 = daddr_ipv4;
gifr.type = NAS_MSG_CLASS_ADD_REQUEST;
err=ioctl(fd, NAS_IOCTL_RRM, &gifr);
if (err == -1) perror("ioctl");
}
if (saddr_ipv6set == 1) {
msgreq_class = (struct nas_msg_class_add_request *)(gifr.msg);
msgreq_class->rab_id = atoi(rb);
msgreq_class->lcr = atoi(cx);
msgreq_class->version = 6;
if (dscpset==0)
msgreq_class->dscp=0;
else
msgreq_class->dscp=atoi(dscp);
msgreq_class->classref = 2+(msgreq_class->lcr<<3);
msgreq_class->dir=NAS_DIRECTION_SEND;
msgreq_class->fct=NAS_FCT_QOS_SEND;
// TO BE FIXED WHEN WE CAN SPECIFY A PROTOCOL-based rule
msgreq_class->protocol = NAS_PROTOCOL_DEFAULT;
memcpy(&msgreq_class->saddr.ipv6,&saddr_ipv6,16);
memcpy(&msgreq_class->daddr.ipv6,&daddr_ipv6,16);
inet_ntop(AF_INET6,(void *)&saddr_ipv6,addr_str,46);
printf("IPV6: Source %s\n",addr_str);
inet_ntop(AF_INET6,(void *)&daddr_ipv6,addr_str,46);
printf("IPV6: Dest %s\n",addr_str);
gifr.type = NAS_MSG_CLASS_ADD_REQUEST;
err=ioctl(fd, NAS_IOCTL_RRM, &gifr);
if (err == -1) perror("ioctl");
msgreq_class->rab_id = atoi(rb);
msgreq_class->lcr = atoi(cx);
msgreq_class->classref = 3+(msgreq_class->lcr<<3);
msgreq_class->dir=NAS_DIRECTION_RECEIVE;
memcpy(&msgreq_class->daddr.ipv6,&saddr_ipv6,16);
memcpy(&msgreq_class->saddr.ipv6,&daddr_ipv6,16);
gifr.type = NAS_MSG_CLASS_ADD_REQUEST;
err=ioctl(fd, NAS_IOCTL_RRM, &gifr);
if (err == -1) perror("ioctl");
}
if (mpls_inlabelset == 1) {
msgreq_class = (struct nas_msg_class_add_request *)(gifr.msg);
msgreq_class->rab_id = atoi(rb);
msgreq_class->lcr = atoi(cx);
msgreq_class->version = NAS_MPLS_VERSION_CODE;
if (dscpset==0)
msgreq_class->dscp=0;
else
msgreq_class->dscp=atoi(dscp);
msgreq_class->classref = 4 + (msgreq_class->lcr<<3);
msgreq_class->dir=NAS_DIRECTION_SEND;
msgreq_class->fct=NAS_FCT_QOS_SEND;
// TO BE FIXED WHEN WE CAN SPECIFY A PROTOCOL-based rule
msgreq_class->protocol = NAS_PROTOCOL_DEFAULT;
mpls_outlabel = atoi(mpls_outgoinglabel);
printf("Setting MPLS outlabel %u with exp %d\n",mpls_outlabel,msgreq_class->dscp);
msgreq_class->daddr.mpls_label = mpls_outlabel;
gifr.type = NAS_MSG_CLASS_ADD_REQUEST;
err=ioctl(fd, NAS_IOCTL_RRM, &gifr);
if (err == -1) perror("ioctl");
msgreq_class->rab_id = atoi(rb);
msgreq_class->lcr = atoi(cx);
msgreq_class->classref = 5 + (msgreq_class->lcr<<3);
msgreq_class->dir=NAS_DIRECTION_RECEIVE;
// TO BE FIXED WHEN WE CAN SPECIFY A PROTOCOL-based rule
msgreq_class->protocol = NAS_PROTOCOL_DEFAULT;
mpls_inlabel = atoi(mpls_incominglabel);
printf("Setting MPLS inlabel %u with exp %d\n",mpls_inlabel,msgreq_class->dscp);
msgreq_class->daddr.mpls_label = mpls_inlabel;
gifr.type = NAS_MSG_CLASS_ADD_REQUEST;
err=ioctl(fd, NAS_IOCTL_RRM, &gifr);
if (err == -1) perror("ioctl");
}
} else if (action == DEL_RB) {
gifr.type = NAS_MSG_RB_RELEASE_REQUEST;
err=ioctl(fd, NAS_IOCTL_RRM, &gifr);
if (err == -1) perror("ioctl");
}
}

View File

@@ -1,149 +0,0 @@
/*
* 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
*/
#include <sys/types.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
typedef unsigned int sdu_size_t;
typedef unsigned int rb_id_t;
typedef struct pdcp_data_req_header_t {
rb_id_t rb_id;
sdu_size_t data_size;
int inst;
} pdcp_data_req_header_t;
typedef struct pdcp_data_ind_header_t {
rb_id_t rb_id;
sdu_size_t data_size;
int inst;
} pdcp_data_ind_header_t;
#define MAX_PAYLOAD 1024 /* maximum payload size*/
struct sockaddr_nl src_addr, dest_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
int sock_fd;
struct msghdr msg;
void foo( int sig )
{
printf("I got cntl-C, closing socket\n");
close(sock_fd);
exit(-1);
}
#define OAI_IP_DRIVER_NETLINK_ID 31
void main()
{
struct sigaction newaction;
int i=0;
int ret;
int len;
newaction.sa_handler = foo;
if ( sigaction( SIGINT, &newaction, NULL ) == -1)
perror("Could not install the new signal handler");
sock_fd = socket(PF_NETLINK, SOCK_RAW,OAI_IP_DRIVER_NETLINK_ID);
printf("Opened socket with fd %d\n",sock_fd);
ret = fcntl(sock_fd,F_SETFL,O_NONBLOCK);
printf("fcntl returns %d\n",ret);
memset(&src_addr, 0, sizeof(src_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = 1;//getpid(); /* self pid */
src_addr.nl_groups = 0; /* not in mcast groups */
ret = bind(sock_fd, (struct sockaddr*)&src_addr,
sizeof(src_addr));
printf("bind returns %d\n",ret);
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.nl_family = AF_NETLINK;
dest_addr.nl_pid = 0; /* For Linux Kernel */
dest_addr.nl_groups = 0; /* unicast */
nlh=(struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
/* Fill the netlink message header */
nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
nlh->nlmsg_pid = 1;//getpid(); /* self pid */
nlh->nlmsg_flags = 0;
iov.iov_base = (void *)nlh;
iov.iov_len = nlh->nlmsg_len;
memset(&msg,0,sizeof(msg));
msg.msg_name = (void *)&dest_addr;
msg.msg_namelen = sizeof(dest_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
/* Read message from kernel */
memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
while (1) {
len = recvmsg(sock_fd, &msg, 0);
if (len<0) {
// exit(-1);
} else {
printf("Received socket with length %d (nlmsg_len = %d)\n",len,nlh->nlmsg_len);
}
usleep(1000);
i=i+1;
if ((i % 100) == 0)
printf("%d\n",i);
/*
for (i=0;i<nlh->nlmsg_len - sizeof(struct nlmsghdr);i++) {
printf("%x ",
((unsigned char *)NLMSG_DATA(nlh))[i]);
}
*/
}
/* Close Netlink Socket */
}

View File

@@ -1,758 +0,0 @@
/*
* 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
*/
/*! \file classifier.c
* \brief Classify IP packets
* \author Navid Nikaein, Lionel GAUTHIER, Raymond knopp
* \company Eurecom
* \email: navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr, knopp@eurecom.fr
*/
#include "local.h"
#include "proto_extern.h"
#include <net/ip6_fib.h>
#include <net/route.h>
//#define MPLS
#ifdef MPLS
#include <net/mpls.h>
#endif
//#define NAS_DEBUG_CLASS 1
//#define NAS_DEBUG_SEND 1
//---------------------------------------------------------------------------
// Add a new classifier rule (send direction)
struct classifier_entity *nas_CLASS_add_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref) {
//---------------------------------------------------------------------------
struct classifier_entity *gc;
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_ADD_SCLASSIFIER: begin for dscp %d, classref %d\n", dscp,classref);
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_ADD_SCLASSIFIER - input parameter cx is NULL \n");
#endif
return NULL;
}
for (gc=cx->sclassifier[dscp]; gc!=NULL; gc=gc->next) {
if (gc->classref==classref) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_ADD_SCLASSIFIER: classifier already exist for dscp %d, classref %d\n",dscp,classref);
#endif
return gc;
}
}
gc=(struct classifier_entity *)kmalloc(sizeof(struct classifier_entity), GFP_KERNEL);
if (gc==NULL)
return NULL;
gc->next=cx->sclassifier[dscp];
gc->classref=classref;
cx->sclassifier[dscp]=gc;
++cx->nsclassifier;
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_ADD_SCLASSIFIER: classifier created for dscp %d, classref %d\n",dscp,classref);
#endif
return gc;
}
//---------------------------------------------------------------------------
// Add a new classifier rule (receive direction)
struct classifier_entity *nas_CLASS_add_rclassifier(uint8_t dscp,
uint16_t classref,
struct nas_priv *gpriv) {
//---------------------------------------------------------------------------
struct classifier_entity *gc;
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_ADD_RCLASSIFIER: begin\n");
#endif
for (gc=gpriv->rclassifier[dscp]; gc!=NULL; gc=gc->next) {
if (gc->classref==classref) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_ADD_RCLASSIFIER: classifier already exist for dscp %d, classref %d\n",dscp,classref);
#endif
return gc;
}
}
gc=(struct classifier_entity *)kmalloc(sizeof(struct classifier_entity), GFP_KERNEL);
if (gc==NULL)
return NULL;
gc->next=gpriv->rclassifier[dscp];
gc->classref=classref;
gpriv->rclassifier[dscp]=gc;
++gpriv->nrclassifier;
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_ADD_RCLASSIFIER: classifier created for dscp %d, classref %d\n",dscp,classref);
#endif
return gc;
}
//---------------------------------------------------------------------------
// Add a new classifier rule (forwarding)
struct classifier_entity *nas_CLASS_add_fclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref) {
//---------------------------------------------------------------------------
struct classifier_entity *gc;
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_ADD_FCLASSIFIER: begin for dscp %d, classref %d\n", dscp,classref);
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_ADD_FCLASSIFIER - input parameter cx is NULL \n");
#endif
return NULL;
}
for (gc=cx->fclassifier[dscp]; gc!=NULL; gc=gc->next) {
if (gc->classref==classref) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_ADD_SCLASSIFIER: classifier already exist for dscp %d, classref %d\n",dscp,classref);
#endif
return gc;
}
}
gc=(struct classifier_entity *)kmalloc(sizeof(struct classifier_entity), GFP_KERNEL);
if (gc==NULL)
return NULL;
gc->next=cx->fclassifier[dscp];
gc->classref=classref;
cx->fclassifier[dscp]=gc;
++cx->nfclassifier;
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_ADD_FCLASSIFIER: classifier created for dscp %d, classref %d\n",dscp,classref);
#endif
return gc;
}
//---------------------------------------------------------------------------
void nas_CLASS_flush_sclassifier(struct cx_entity *cx) {
//---------------------------------------------------------------------------
uint8_t dscpi;
struct classifier_entity *gc;
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_FLUSH_SCLASSIFIER: begin\n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_FLUSH_SCLASSIFIER - input parameter cx is NULL \n");
#endif
return;
}
//
for (dscpi=0; dscpi<NAS_DSCP_MAX; ++dscpi) {
for (gc=cx->sclassifier[dscpi]; gc!=NULL; gc=cx->sclassifier[dscpi]) {
cx->sclassifier[dscpi]=gc->next;
kfree(gc);
}
}
cx->nsclassifier=0;
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_FLUSH_SCLASSIFIER: end\n");
#endif
}
//---------------------------------------------------------------------------
void nas_CLASS_flush_fclassifier(struct cx_entity *cx) {
//---------------------------------------------------------------------------
uint8_t dscpi;
struct classifier_entity *gc;
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_FLUSH_FCLASSIFIER: begin\n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_FLUSH_FCLASSIFIER - input parameter cx is NULL \n");
#endif
return;
}
//
for (dscpi=0; dscpi<NAS_DSCP_MAX; ++dscpi) {
for (gc=cx->fclassifier[dscpi]; gc!=NULL; gc=cx->fclassifier[dscpi]) {
cx->fclassifier[dscpi]=gc->next;
kfree(gc);
}
}
cx->nfclassifier=0;
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_FLUSH_FCLASSIFIER: end\n");
#endif
}
//---------------------------------------------------------------------------
void nas_CLASS_flush_rclassifier(struct nas_priv *gpriv) {
//---------------------------------------------------------------------------
uint8_t dscpi;
struct classifier_entity *gc;
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_FLUSH_RCLASSIFIER: begin\n");
#endif
for (dscpi=0; dscpi<NAS_DSCP_MAX; ++dscpi) {
for (gc=gpriv->rclassifier[dscpi]; gc!=NULL; gc=gpriv->rclassifier[dscpi]) {
gpriv->rclassifier[dscpi]=gc->next;
kfree(gc);
}
}
gpriv->nrclassifier=0;
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_FLUSH_RCLASSIFIER: end\n");
#endif
}
//---------------------------------------------------------------------------
// Delete a classifier rule (send direction)
void nas_CLASS_del_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref) {
//---------------------------------------------------------------------------
struct classifier_entity *p,*np;
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_DEL_SCLASSIFIER: begin\n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_DEL_SCLASSIFIER - input parameter cx is NULL \n");
#endif
return;
}
//
p=cx->sclassifier[dscp];
if (p==NULL)
return;
if (p->classref==classref) {
cx->sclassifier[dscp]=p->next;
kfree(p);
--cx->nsclassifier;
return;
}
for (np=p->next; np!=NULL; p=np) {
if (np->classref==classref) {
p->next=np->next;
kfree(np);
--cx->nsclassifier;
return;
}
}
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_DEL_SCLASSIFIER: end\n");
#endif
}
//---------------------------------------------------------------------------
// Delete a classifier rule (send direction)
void nas_CLASS_del_fclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref) {
//---------------------------------------------------------------------------
struct classifier_entity *p,*np;
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_DEL_FCLASSIFIER: begin\n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_DEL_FCLASSIFIER - input parameter cx is NULL \n");
#endif
return;
}
//
p=cx->fclassifier[dscp];
if (p==NULL)
return;
if (p->classref==classref) {
cx->fclassifier[dscp]=p->next;
kfree(p);
--cx->nfclassifier;
return;
}
for (np=p->next; np!=NULL; p=np) {
if (np->classref==classref) {
p->next=np->next;
kfree(np);
--cx->nfclassifier;
return;
}
}
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_DEL_FCLASSIFIER: end\n");
#endif
}
//---------------------------------------------------------------------------
// Delete a classifier rule (receive direction)
void nas_CLASS_del_rclassifier(uint8_t dscp, uint16_t classref,struct nas_priv *gpriv) {
//---------------------------------------------------------------------------
struct classifier_entity *p,*np;
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_DEL_RCLASSIFIER: begin\n");
#endif
p=gpriv->rclassifier[dscp];
if (p==NULL)
return;
if (p->classref==classref) {
gpriv->rclassifier[dscp]=p->next;
kfree(p);
--gpriv->nrclassifier;
return;
}
for (np=p->next; np!=NULL; p=np) {
if (np->classref==classref) {
p->next=np->next;
kfree(np);
--gpriv->nrclassifier;
return;
}
}
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_DEL_RCLASSIFIER: end\n");
#endif
}
//---------------------------------------------------------------------------
// Search the entity with the IPv6 address 'addr'
// Navid: the ipv6 classifier is not fully tested
struct cx_entity *nas_CLASS_cx6(struct sk_buff *skb,
unsigned char dscp,
struct nas_priv *gpriv,
int inst,
unsigned char *cx_searcher) {
//---------------------------------------------------------------------------
unsigned char cxi;
unsigned int *addr,*dst=NULL;
struct cx_entity *default_ip=NULL;
struct classifier_entity *p=NULL;
if (skb!=NULL) {
for (cxi=*cx_searcher; cxi<NAS_CX_MAX; cxi++) {
(*cx_searcher)++;
p = gpriv->cx[cxi].sclassifier[dscp];
while (p!=NULL) {
if (p->version == 6) { // verify that this is an IPv4 rule
if ((addr = (unsigned int *)(&(p->daddr.ipv6)))== NULL) {
printk("nas_CLASS_cx6: addr is null \n");
p = p->next;
continue;
}
#ifdef NAS_DEBUG_CLASS
printk("cx %d : %X,%X.%X,%X\n",cxi,addr[0],addr[1],addr[2],addr[3]);
#endif //NAS_DEBUG_CLASS
if ( (dst = &((struct iphdr *)(skb_network_header(skb)))->daddr) == NULL) {
printk("nas_CLASS_cx6: dst addr is null \n");
p = p->next;
continue;
}
if ((addr[0] == dst[0]) &&
(addr[1] == dst[1]) &&
(addr[2] == dst[2]) &&
(addr[3] == dst[3])) {
//#ifdef NAS_DEBUG_CLASS
printk("nas_CLASS_cx6: found cx %d: %X.%X.%X.%X\n",cxi,
dst[0],
dst[1],
dst[2],
dst[3]);
//#endif //NAS_DEBUG_CLASS
return gpriv->cx+cxi;
}
/*
else if ((addr[0]==NAS_DEFAULT_IPV6_ADDR0) &&
(addr[1]==NAS_DEFAULT_IPV6_ADDR1) &&
(addr[2]==NAS_DEFAULT_IPV6_ADDR2) &&
(addr[3]==NAS_DEFAULT_IPV6_ADDR3))
default_ip = gpriv->cx+cxi;
*/
}
// Go to next classifier entry for connection
p = p->next;
}
}
}
if (dst ) {
printk("nas_CLASS_cx6 NOT FOUND: %X.%X.%X.%X\n",
dst[0],
dst[1],
dst[2],
dst[3]);
}
return default_ip;
}
//---------------------------------------------------------------------------
// Search the entity with the IPv4 address 'addr'
struct cx_entity *nas_CLASS_cx4(struct sk_buff *skb,
unsigned char dscp,
struct nas_priv *gpriv,
int inst,
unsigned char *cx_searcher) {
//---------------------------------------------------------------------------
unsigned char cxi;
unsigned char *addr;
uint32_t daddr;
struct cx_entity *default_ip=NULL;
struct classifier_entity *p=NULL;
// if (inst >0)
// return(gpriv->cx); //dump to clusterhead
if (skb!=NULL) {
daddr = ((struct iphdr *)(skb_network_header(skb)))->daddr;
if (daddr!=0) {
#ifdef NAS_DEBUG_CLASS
printk("[NAS][CLASS][IPv4] Searching for %d.%d.%d.%d\n",
((unsigned char *)&daddr)[0],
((unsigned char *)&daddr)[1],
((unsigned char *)&daddr)[2],
((unsigned char *)&daddr)[3]);
#endif
for (cxi=*cx_searcher; cxi<NAS_CX_MAX; ++cxi) {
(*cx_searcher)++;
p = gpriv->cx[cxi].sclassifier[dscp];
while (p!=NULL) {
if (p->version == 4) { // verify that this is an IPv4 rule
#ifdef NAS_DEBUG_CLASS
addr = (char *)(&(p->daddr.ipv4));
printk("found classifier cx %d for destination: %d.%d.%d.%d\n",cxi,addr[0],addr[1],addr[2],addr[3]);
#endif //NAS_DEBUG_CLASS
if ((p->daddr.ipv4)== daddr) {
addr = (char *)(&(p->daddr.ipv4));
#ifdef NAS_DEBUG_CLASS
printk("found cx %d: %d.%d.%d.%d\n",cxi,
addr[0],
addr[1],
addr[2],
addr[3]);
#endif //NAS_DEBUG_CLASS
return gpriv->cx+cxi;
}
/*
else if (gpriv->cx[cxi].sclassifier[dscp]->daddr.ipv4==NAS_DEFAULT_IPV4_ADDR) {
#ifdef NAS_DEBUG_CLASS
printk("found default_ip rule\n");
#endif //NAS_DEBUG_CLASS
default_ip = gpriv->cx+cxi;
}
*/
}
// goto to next classification rule for the connection
p = p->next;
}
}
}
}
return default_ip;
}
#ifdef MPLS
//---------------------------------------------------------------------------
// Search the entity with the mpls label and given exp
struct cx_entity *nas_CLASS_MPLS(struct sk_buff *skb,
unsigned char exp,
struct nas_priv *gpriv,
int inst,
unsigned char *cx_searcher) {
//---------------------------------------------------------------------------
unsigned char cxi;
struct cx_entity *default_label=NULL;
struct classifier_entity *p=NULL;
// if (inst >0)
// return(gpriv->cx); //dump to clusterhead
#ifdef NAS_DEBUG_CLASS
printk("[NAS][CLASS][MPLS] Searching for label %d\n",MPLSCB(skb)->label);
#endif
for (cxi=*cx_searcher; cxi<NAS_CX_MAX; ++cxi) {
(*cx_searcher)++;
p = gpriv->cx[cxi].sclassifier[exp];
while (p!=NULL) {
if (p->version == NAS_MPLS_VERSION_CODE) { // verify that this is an MPLS rule
#ifdef NAS_DEBUG_CLASS
printk("cx %d : label %d\n",cxi,p->daddr.mpls_label);
#endif //NAS_DEBUG_CLASS
if (p->daddr.mpls_label==MPLSCB(skb)->label) {
#ifdef NAS_DEBUG_CLASS
printk("found cx %d: label %d, RB %d\n",cxi,
MPLSCB(skb)->label,
p->rab_id);
#endif //NAS_DEBUG_CLASS
return gpriv->cx+cxi;
}
/*
else if (gpriv->cx[cxi].sclassifier[dscp]->daddr.ipv4==NAS_DEFAULT_IPV4_ADDR) {
#ifdef NAS_DEBUG_CLASS
printk("found default_ip rule\n");
#endif //NAS_DEBUG_CLASS
default_ip = gpriv->cx+cxi;
}
*/
}
// goto to next classification rule for the connection
p = p->next;
}
}
return default_label;
}
#endif
//---------------------------------------------------------------------------
// Search the sending function
void nas_CLASS_send(struct sk_buff *skb,int inst) {
//---------------------------------------------------------------------------
struct classifier_entity *p, *sp;
uint8_t *protocolh,version;
uint8_t protocol, dscp /*, exp,label*/ ;
uint16_t classref;
struct cx_entity *cx;
//unsigned int i;
//unsigned int router_adv = 0;
struct net_device *dev=nasdev[inst];
struct nas_priv *gpriv=netdev_priv(dev);
unsigned char cx_searcher,no_connection=1;
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_SEND: begin - inst %d\n",inst);
#endif
if (skb==NULL) {
#ifdef NAS_DEBUG_SEND
printk("NAS_CLASS_SEND - input parameter skb is NULL \n");
#endif
return;
}
#ifdef NAS_DEBUG_SEND
printk("[NAS][CLASS][SEND] Got packet from kernel:\n");
for (int i=0; i<256; i++)
printk("%2x ",((unsigned char *)skb->data)[i]);
printk("\n");
#endif
// find all connections related to socket
cx_searcher = 0;
no_connection = 1;
//while (cx_searcher<NAS_CX_MAX) {
cx = NULL;
// Address classification
switch (ntohs(skb->protocol)) {
case ETH_P_IPV6:
version = 6;
protocolh=nas_TOOL_get_protocol6(
(struct ipv6hdr *)(skb_network_header(skb)),
&protocol);
dscp=nas_TOOL_get_dscp6(
(struct ipv6hdr *)(skb_network_header(skb))
);
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_SEND: %p %d %p %d %p \n",skb, dscp, gpriv, inst, &cx_searcher);
#endif
cx=nas_CLASS_cx6(skb,dscp,gpriv,inst,&cx_searcher);
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_SEND: Got IPv6 packet, dscp = %d\n",dscp);
#endif
break;
case ETH_P_IP:
dscp=nas_TOOL_get_dscp4((struct iphdr *)(skb_network_header(skb)));
cx=nas_CLASS_cx4(skb,dscp,gpriv,inst,&cx_searcher);
protocolh=nas_TOOL_get_protocol4(
(struct iphdr *)(skb_network_header(skb)),
&protocol);
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_SEND: Got IPv4 packet (%x), dscp = %d, cx = %x\n",ntohs(skb->protocol),dscp,cx);
#endif
version = 4;
break;
#ifdef MPLS
case ETH_P_MPLS_UC:
cx=nas_CLASS_MPLS(skb,MPLSCB(skb)->exp,gpriv,inst,&cx_searcher);
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_SEND: Got MPLS unicast packet, exp = %d, label = %d, cx = %x\n",MPLSCB(skb)->exp,MPLSCB(skb)->label,cx);
#endif
dscp = MPLSCB(skb)->exp;
version = NAS_MPLS_VERSION_CODE;
protocol = version;
break;
#endif
default:
printk("NAS_CLASS_SEND: Unknown protocol\n");
version = 0;
return;
}
// If a valid connection for the DSCP/EXP with destination address
// is found scan all protocol-based classification rules
if (cx) {
classref=0;
sp=NULL;
#ifdef NAS_DEBUG_CLASS
printk("[NAS][CLASSIFIER] DSCP/EXP %d : looking for classifier entry\n",dscp);
#endif
for (p=cx->sclassifier[dscp]; p!=NULL; p=p->next) {
#ifdef NAS_DEBUG_CLASS
printk("[NAS][CLASSIFIER] DSCP %d p->classref=%d,p->protocol=%d,p->version=%d\n",dscp,p->classref,p->protocol,p->version);
#endif
// Check if transport protocol/message match
/*
if ((p->protocol == protocol))
if ((protocol == NAS_PROTOCOL_ICMP6) && (version == 6))
if (p->protocol_message_type == (p->protocol_message_type )) {
printk("[GRAAL][CLASSIFIER] Router advertisement\n");
}
*/
// normal rule checks that network protocol version matches
if (p->version == version) {
sp=p;
classref=sp->classref;
break;
}
}
if (sp!=NULL) {
#ifdef NAS_DEBUG_CLASS
char sfct[10], sprotocol[10];
if (sp->fct==nas_COMMON_QOS_send)
strcpy(sfct, "qos");
if (sp->fct==nas_CTL_send)
strcpy(sfct, "ctl");
if (sp->fct==nas_COMMON_del_send)
strcpy(sfct, "del");
if (sp->fct==nas_mesh_DC_send_sig_data_request)
strcpy(sfct, "dc");
switch(protocol) {
case NAS_PROTOCOL_UDP:
strcpy(sprotocol, "udp");
printk("udp packet\n");
break;
case NAS_PROTOCOL_TCP:
strcpy(sprotocol, "tcp");
printk("tcp packet\n");
break;
case NAS_PROTOCOL_ICMP4:
strcpy(sprotocol, "icmp4");
printk("icmp4 packet\n");
break;
case NAS_PROTOCOL_ICMP6:
strcpy(sprotocol, "icmp6");
print_TOOL_pk_icmp6((struct icmp6hdr *)protocolh);
break;
#ifdef MPLS
case NAS_MPLS_VERSION_CODE:
strcpy(sprotocol,"mpls");
break;
#endif
}
printk("NAS_CLASS_SEND: (dscp %u, %s) received, (classref %u, fct %s, rab_id %u) classifier rule\n",
dscp, sprotocol, sp->classref, sfct, sp->rab_id);
#endif
sp->fct(skb, cx, sp,inst, NULL);
} // if classifier entry match found
else {
printk("NAS_CLASS_SEND: no corresponding item in the classifier, so the message is dropped\n");
// nas_COMMON_del_send(skb, cx, NULL,inst);
}
no_connection = 0;
} // if connection found
#ifdef NAS_DEBUG_CLASS
if (no_connection == 1)
printk("NAS_CLASS_SEND: no corresponding connection, so the message is dropped\n");
#endif /* NAS_DEBUG_CLASS */
// } // while loop over connections
#ifdef NAS_DEBUG_CLASS
printk("NAS_CLASS_SEND: end\n");
#endif
}

View File

@@ -1,618 +0,0 @@
/*
* 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
*/
/*! \file common.c
* \brief implementation of emultor tx and rx
* \author Navid Nikaein, Lionel GAUTHIER, and Raymomd Knopp
* \date 2011
* \version 1.0
* \company Eurecom
* \email: navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
#include "local.h"
#include "proto_extern.h"
//#define NAS_DEBUG_RECEIVE 1
//#define NAS_DEBUG_SEND 1
//#define NAS_DEBUG_CLASS 1
//#define NAS_ADDRESS_FIX 1
#include <linux/inetdevice.h>
#include <net/tcp.h>
#include <net/udp.h>
void nas_COMMON_receive(uint16_t dlen,
void *pdcp_sdu,
int inst,
struct classifier_entity *rclass,
nasRadioBearerId_t rb_id)
{
//---------------------------------------------------------------------------
struct sk_buff *skb;
struct ipversion *ipv;
struct nas_priv *gpriv=netdev_priv(nasdev[inst]);
//int i;
unsigned char protocol;
//struct udphdr *uh;
//struct tcphdr *th;
struct iphdr *network_header;
#ifdef NAS_DEBUG_RECEIVE
printk("NAS_COMMON_RECEIVE: begin RB %d Inst %d Length %d bytes\n",rb_id,inst,dlen);
#endif
skb = dev_alloc_skb( dlen + 2 );
if(!skb) {
printk("NAS_COMMON_RECEIVE: low on memory\n");
++gpriv->stats.rx_dropped;
return;
}
skb_reserve(skb,2);
memcpy(skb_put(skb, dlen), pdcp_sdu,dlen);
skb->dev = nasdev[inst];
skb_reset_mac_header(skb);
//printk("[NAC_COMMIN_RECEIVE]: Packet Type %d (%d,%d)",skb->pkt_type,PACKET_HOST,PACKET_BROADCAST);
skb->pkt_type = PACKET_HOST;
if (rclass->version != NAS_MPLS_VERSION_CODE) { // This is an IP packet
skb->ip_summed = CHECKSUM_NONE;
ipv = (struct ipversion *)skb->data;
switch (ipv->version) {
case 6:
#ifdef NAS_DEBUG_RECEIVE
printk("NAS_COMMON_RECEIVE: receive IPv6 message\n");
#endif
skb_reset_network_header(skb);
skb->protocol = htons(ETH_P_IPV6);
// printk("Writing packet with protocol %x\n",ntohs(skb->protocol));
break;
case 4:
#ifdef NAS_ADDRESS_FIX
// Make the third byte of both the source and destination equal to the fourth of the destination
unsigned char * ifaddr, *saddr, daddr;
uint32_t odaddr = 0, osaddr;
daddr = (unsigned char *)&((struct iphdr *)skb->data)->daddr;
odaddr = ((struct iphdr *)skb->data)->daddr;
//sn = addr[3];
saddr = (unsigned char *)&((struct iphdr *)skb->data)->saddr;
osaddr = ((struct iphdr *)skb->data)->saddr;
if (daddr[0] == saddr[0]) {// same network
daddr[2] = daddr[3]; // set third byte of destination to that of local machine so that local IP stack accepts the packet
saddr[2] = daddr[3]; // set third byte of source to that of local machine so that local IP stack accepts the packet
} else { // get the 3rd byte from device address in net_device structure
ifaddr = (unsigned char *)(&(((struct in_device *)((nasdev[inst])->ip_ptr))->ifa_list->ifa_local));
if (saddr[0] == ifaddr[0]) { // source is in same network as local machine
daddr[0] += saddr[3]; // fix address of remote destination to undo change at source
saddr[2] = ifaddr[2]; // set third byte to that of local machine so that local IP stack accepts the packet
} else { // source is remote machine from outside network
saddr[0] -= daddr[3]; // fix address of remote source to be understood by destination
daddr[2] = daddr[3]; // fix 3rd byte of local address to be understood by IP stack of
// destination
}
}
#endif //NAS_ADDRESS_FIX
#ifdef NAS_DEBUG_RECEIVE
// printk("NAS_TOOL_RECEIVE: receive IPv4 message\n");
addr = (unsigned char *)&((struct iphdr *)skb->data)->saddr;
if (addr) {
// addr[2]^=0x01;
printk("[NAS][COMMON][RECEIVE] Source %d.%d.%d.%d\n",addr[0],addr[1],addr[2],addr[3]);
}
addr = (unsigned char *)&((struct iphdr *)skb->data)->daddr;
if (addr) {
// addr[2]^=0x01;
printk("[NAS][COMMON][RECEIVE] Dest %d.%d.%d.%d\n",addr[0],addr[1],addr[2],addr[3]);
}
printk("[NAS][COMMON][RECEIVE] protocol %d\n",((struct iphdr *)skb->data)->protocol);
#endif
skb_reset_network_header(skb);
network_header = (struct iphdr *)skb_network_header(skb);
protocol = network_header->protocol;
#ifdef NAS_DEBUG_RECEIVE
switch (protocol) {
case IPPROTO_IP:
printk("[NAS][COMMON][RECEIVE] Received Raw IPv4 packet\n");
break;
case IPPROTO_IPV6:
printk("[NAS][COMMON][RECEIVE] Received Raw IPv6 packet\n");
break;
case IPPROTO_ICMP:
printk("[NAS][COMMON][RECEIVE] Received Raw ICMP packet\n");
break;
case IPPROTO_TCP:
printk("[NAS][COMMON][RECEIVE] Received TCP packet\n");
break;
case IPPROTO_UDP:
printk("[NAS][COMMON][RECEIVE] Received UDP packet\n");
break;
default:
break;
}
#endif
#ifdef NAS_ADDRESS_FIX
#ifdef NAS_DEBUG_RECEIVE
printk("NAS_COMMON_RECEIVE: dumping the packet before the csum recalculation (len %d)\n",skb->len);
for (i=0; i<skb->len; i++)
printk("%2x ",((unsigned char *)(skb->data))[i]);
printk("\n");
#endif //NAS_DEBUG_RECEIVE
network_header->check = 0;
network_header->check = ip_fast_csum((unsigned char *) network_header,
network_header->ihl);
#ifdef NAS_DEBUG_RECEIVE
printk("[NAS][COMMON][RECEIVE] IP Fast Checksum %x \n", network_header->check);
#endif
// if (!(skb->nh.iph->frag_off & htons(IP_OFFSET))) {
switch(protocol) {
case IPPROTO_TCP:
uint16_t *cksum,check;
cksum = (uint16_t*)&(((struct tcphdr*)(((char *)network_header + (network_header->ihl<<2))))->check);
//check = csum_tcpudp_magic(((struct iphdr *)network_header)->saddr, ((struct iphdr *)network_header)->daddr, tcp_hdrlen(skb), IPPROTO_TCP, ~(*cksum));
#ifdef NAS_DEBUG_RECEIVE
printk("[NAS][COMMON] Inst %d TCP packet calculated CS %x, CS = %x (before), SA (%x)%x, DA (%x)%x\n",
inst,
network_header->check,
*cksum,
osaddr,
((struct iphdr *)skb->data)->saddr,
odaddr,
((struct iphdr *)skb->data)->daddr);
#endif
check = csum_tcpudp_magic(((struct iphdr *)skb->data)->saddr, ((struct iphdr *)skb->data)->daddr,0,0, ~(*cksum));
*cksum = csum_tcpudp_magic(~osaddr, ~odaddr, 0, 0, ~check);
#ifdef NAS_DEBUG_RECEIVE
printk("[NAS][COMMON] Inst %d TCP packet NEW CS %x\n",
inst,
*cksum);
#endif
break;
case IPPROTO_UDP:
cksum = (uint16_t*)&(((struct udphdr*)(((char *)network_header + (network_header->ihl<<2))))->check);
// check = csum_tcpudp_magic(((struct iphdr *)network_header)->saddr, ((struct iphdr *)network_header)->daddr, udp_hdr(skb)->len, IPPROTO_UDP, ~(*cksum));
#ifdef NAS_DEBUG_RECEIVE
printk("[NAS][COMMON] Inst %d UDP packet CS = %x (before), SA (%x)%x, DA (%x)%x\n",
inst,
*cksum,
osaddr,
((struct iphdr *)skb->data)->saddr,
odaddr,
((struct iphdr *)skb->data)->daddr);
#endif
check = csum_tcpudp_magic(((struct iphdr *)skb->data)->saddr, ((struct iphdr *)skb->data)->daddr, 0,0, ~(*cksum));
*cksum= csum_tcpudp_magic(~osaddr, ~odaddr,0,0, ~check);
//*cksum= csum_tcpudp_magic(~osaddr, ~odaddr,udp_hdr(skb)->len, IPPROTO_UDP, ~check);
#ifdef NAS_DEBUG_RECEIVE
printk("[NAS][COMMON] Inst %d UDP packet NEW CS %x\n",
inst,
*cksum);
#endif
// if ((check = *cksum) != 0) {
// src, dst, len, proto, sum
// }
break;
default:
break;
}
// }
#endif //NAS_ADDRESS_FIX
skb->protocol = htons(ETH_P_IP);
// printk("[NAS][COMMON] Writing packet with protocol %x\n",ntohs(skb->protocol));
break;
default:
printk("NAS_COMMON_RECEIVE: begin RB %d Inst %d Length %d bytes\n",rb_id,inst,dlen);
printk("[NAS][COMMON] Inst %d: receive unknown message (version=%d)\n",inst,ipv->version);
}
} else { // This is an MPLS packet
#ifdef NAS_DEBUG_RECEIVE
printk("NAS_COMMON_RECEIVE: Received an MPLS packet on RB %d\n",rb_id);
#endif
skb->protocol = htons(ETH_P_MPLS_UC);
}
++gpriv->stats.rx_packets;
gpriv->stats.rx_bytes += dlen;
#ifdef NAS_DEBUG_RECEIVE
printk("NAS_COMMON_RECEIVE: sending packet of size %d to kernel\n",skb->len);
for (i=0; i<skb->len; i++)
printk("%2x ",((unsigned char *)(skb->data))[i]);
printk("\n");
#endif //NAS_DEBUG_RECEIVE
netif_rx_ni(skb);
#ifdef NAS_DEBUG_RECEIVE
printk("NAS_COMMON_RECEIVE: end\n");
#endif
}
//---------------------------------------------------------------------------
// Delete the data
void nas_COMMON_del_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *sp,int inst,struct nas_priv *gpriv)
{
struct nas_priv *priv=netdev_priv(nasdev[inst]);
//---------------------------------------------------------------------------
++priv->stats.tx_dropped;
}
//---------------------------------------------------------------------------
// Request the transfer of data (QoS SAP)
void nas_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,int inst, struct nas_priv *gpriv)
{
//---------------------------------------------------------------------------
struct pdcp_data_req_header_s pdcph;
struct nas_priv *priv=netdev_priv(nasdev[inst]);
#ifdef LOOPBACK_TEST
int i;
#endif
unsigned int bytes_wrote;
//unsigned char j;
// Start debug information
#ifdef NAS_DEBUG_SEND
printk("NAS_COMMON_QOS_SEND - inst %d begin \n",inst);
#endif
// if (cx->state!=NAS_STATE_CONNECTED) // <--- A REVOIR
// {
// priv->stats.tx_dropped ++;
// printk("NAS_QOS_SEND: No connected, so message are dropped \n");
// return;
// }
if (skb==NULL) {
#ifdef NAS_DEBUG_SEND
printk("NAS_COMMON_QOS_SEND - input parameter skb is NULL \n");
#endif
return;
}
if (gc==NULL) {
#ifdef NAS_DEBUG_SEND
printk("NAS_COMMON_QOS_SEND - input parameter gc is NULL \n");
#endif
return;
}
if (cx==NULL) {
#ifdef NAS_DEBUG_SEND
printk("NAS_COMMON_QOS_SEND - input parameter cx is NULL \n");
#endif
return;
}
// End debug information
if (gc->rb==NULL) {
gc->rb=nas_COMMON_search_rb(cx, gc->rab_id);
if (gc->rb==NULL) {
++priv->stats.tx_dropped;
printk("NAS_COMMON_QOS_SEND: No corresponding Radio Bearer, so message are dropped, rab_id=%u \n", gc->rab_id);
return;
}
}
#ifdef NAS_DEBUG_SEND
printk("NAS_COMMON_QOS_SEND #1 :");
printk("lcr %u, rab_id %u, rab_id %u, skb_len %d\n", cx->lcr, (gc->rb)->rab_id, gc->rab_id,skb->len);
nas_print_classifier(gc);
#endif
pdcph.data_size = skb->len;
pdcph.rb_id = (gc->rb)->rab_id;
pdcph.inst = inst;
pdcph.sourceL2Id = 0;
pdcph.destinationL2Id = 0;
bytes_wrote = nas_netlink_send((char *)&pdcph,NAS_PDCPH_SIZE);
#ifdef NAS_DEBUG_SEND
printk("[NAS] Wrote %d bytes (header for %d byte skb) to PDCP via netlink\n",
bytes_wrote,skb->len);
#endif
if (bytes_wrote != NAS_PDCPH_SIZE) {
printk("NAS_COMMON_QOS_SEND: problem while writing PDCP's header (bytes wrote = %d )\n",bytes_wrote);
printk("rb_id %ld, Wrote %d, Header Size %lu\n", pdcph.rb_id , bytes_wrote, NAS_PDCPH_SIZE);
return;
}
bytes_wrote += nas_netlink_send((char *)skb->data,skb->len);
if (bytes_wrote != skb->len+NAS_PDCPH_SIZE) {
printk("NAS_COMMON_QOS_SEND: Inst %d, RB_ID %ld: problem while writing PDCP's data, bytes_wrote = %d, Data_len %d, PDCPH_SIZE %lu\n",
inst,
pdcph.rb_id,
bytes_wrote,
skb->len,
NAS_PDCPH_SIZE); // congestion
return;
}
#ifdef NAS_DEBUG_SEND
printk("NAS_SEND: Sending packet of size %d to PDCP \n",skb->len);
for (j=0; j<skb->len; j++)
printk("%2x ",((unsigned char *)(skb->data))[j]);
printk("\n");
#endif
priv->stats.tx_bytes += skb->len;
priv->stats.tx_packets ++;
#ifdef NAS_DEBUG_SEND
printk("NAS_COMMON_QOS_SEND - end \n");
#endif
}
void nas_COMMON_QOS_receive(struct nlmsghdr *nlh)
{
struct pdcp_data_ind_header_s *pdcph = (struct pdcp_data_ind_header_s *)NLMSG_DATA(nlh);
struct classifier_entity *rclass;
struct nas_priv *priv;
priv = netdev_priv(nasdev[pdcph->inst]);
#ifdef NAS_DEBUG_RECEIVE
printk("[NAS][COMMON][NETLINK] QOS receive from PDCP, size %d, rab %d, inst %d\n",
pdcph->data_size,pdcph->rb_id,pdcph->inst);
#endif //NAS_DEBUG_RECEIVE
rclass = nas_COMMON_search_class_for_rb(pdcph->rb_id,priv);
if (rclass) {
#ifdef NAS_DEBUG_RECEIVE
printk("[NAS][COMMON][NETLINK] Found corresponding connection in classifier for RAB\n");
#endif //NAS_DEBUG_RECEIVE
nas_COMMON_receive(pdcph->data_size,
(unsigned char *)NLMSG_DATA(nlh) + NAS_PDCPH_SIZE,
pdcph->inst,
rclass,
pdcph->rb_id);
}
}
//---------------------------------------------------------------------------
struct cx_entity *nas_COMMON_search_cx(nasLocalConnectionRef_t lcr,struct nas_priv *priv)
{
//---------------------------------------------------------------------------
#ifdef NAS_DEBUG_CLASS
printk("NAS_COMMON_SEARCH_CX - lcr %d\n",lcr);
#endif
if (lcr<NAS_CX_MAX)
return priv->cx+lcr;
else
return NULL;
}
//---------------------------------------------------------------------------
// Search a Radio Bearer
struct rb_entity *nas_COMMON_search_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id)
{
//---------------------------------------------------------------------------
struct rb_entity *rb;
#ifdef NAS_DEBUG_CLASS
printk("NAS_COMMON_SEARCH_RB - rab_id %d\n", rab_id);
#endif
for (rb=cx->rb; rb!=NULL; rb=rb->next) {
#ifdef NAS_DEBUG_CLASS
printk("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS\n");
printk("NAS_COMMON_SEARCH_RB - rab_id %d Comparing rb_entity.rab_id %u \n", rb->rab_id, rab_id);
//printk("NAS_COMMON_SEARCH_RB - rab_id %d Comparing rb_entity.sapi %u \n", rb->sapi);
//printk("NAS_COMMON_SEARCH_RB - rab_id %d Comparing rb_entity.qos %u \n", rb->qos);
//printk("NAS_COMMON_SEARCH_RB - rab_id %d Comparing rb_entity.state %u \n", rb->state);
//printk("NAS_COMMON_SEARCH_RB - rab_id %d Comparing rb_entity.retry %u \n", rb->retry);
//printk("NAS_COMMON_SEARCH_RB - rab_id %d Comparing rb_entity.countimer %u \n\n", rb->countimer);
#endif
if (rb->rab_id==rab_id)
return rb;
}
return NULL;
}
//
// Search for a classifier with corresponding radio bearer
struct classifier_entity *nas_COMMON_search_class_for_rb(nasRadioBearerId_t rab_id,struct nas_priv *priv)
{
//struct rb_entity *rb;
int dscp;
struct classifier_entity *rclass;
#ifdef NAS_DEBUG_CLASS
printk("[NAS][COMMON] NAS_COMMON_SEARCH_CLASS_FOR_RB - rab_id %d\n", rab_id);
#endif
for (dscp=0; dscp<NAS_DSCP_MAX; dscp++) {
// printk("[NAS][COMMON] priv->rclassifier[%d] = %p\n",dscp,priv->rclassifier[dscp]);
for (rclass=priv->rclassifier[dscp]; rclass!=NULL; rclass=rclass->next) {
#ifdef NAS_DEBUG_CLASS
printk("[NAS][COMMON] NAS_COMMON_SEARCH_CLASS_FOR_RB - dscp %d, rb %d\n", dscp,rclass->rab_id);
#endif
if (rclass->rab_id==rab_id)
return rclass;
}
}
return NULL;
}
//---------------------------------------------------------------------------
struct rb_entity *nas_COMMON_add_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id, nasQoSTrafficClass_t qos)
{
//--------------------------------------------------------------------------
struct rb_entity *rb;
#ifdef NAS_DEBUG_CLASS
printk("NAS_COMMON_ADD_RB - begin for rab_id %d , qos %d\n", rab_id, qos );
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_COMMON_ADD_RB - input parameter cx is NULL \n");
#endif
return NULL;
}
rb=nas_COMMON_search_rb(cx, rab_id);
if (rb==NULL) {
rb=(struct rb_entity *)kmalloc(sizeof(struct rb_entity), GFP_KERNEL);
if (rb!=NULL) {
rb->retry=0;
rb->countimer=NAS_TIMER_IDLE;
rb->rab_id=rab_id;
// rb->rab_id=rab_id+(32*cx->lcr);
#ifdef NAS_DEBUG_DC
printk("NAS_COMMON_ADD_RB: rab_id=%u, mt_id=%u\n",rb->rab_id, cx->lcr);
#endif
rb->qos=qos;
rb->sapi=NAS_RAB_INPUT_SAPI;
rb->state=NAS_IDLE;
rb->next=cx->rb;
cx->rb=rb;
++cx->num_rb;
} else
printk("NAS_ADD_CTL_RB: no memory\n");
}
#ifdef NAS_DEBUG_CLASS
printk("NAS_COMMON_ADD_RB - end \n" );
#endif
return rb;
}
//---------------------------------------------------------------------------
void nas_COMMON_flush_rb(struct cx_entity *cx)
{
//---------------------------------------------------------------------------
struct rb_entity *rb;
struct classifier_entity *gc;
uint8_t dscp;
// End debug information
#ifdef NAS_DEBUG_CLASS
printk("NAS_COMMON_FLUSH_RB - begin\n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_COMMON_FLUSH_RB - input parameter cx is NULL \n");
#endif
return;
}
// End debug information
for (rb=cx->rb; rb!=NULL; rb=cx->rb) {
printk("NAS_COMMON_FLUSH_RB: del rab_id %u\n", rb->rab_id);
cx->rb=rb->next;
kfree(rb);
}
cx->num_rb=0;
cx->rb=NULL;
for(dscp=0; dscp<NAS_DSCP_MAX; ++dscp) {
for (gc=cx->sclassifier[dscp]; gc!=NULL; gc=gc->next)
gc->rb=NULL;
}
#ifdef NAS_DEBUG_CLASS
printk("NAS_COMMON_FLUSH_RB - end\n");
#endif
}

View File

@@ -1,173 +0,0 @@
/*
* 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
*/
#ifndef _NAS_CST
#define _NAS_CST
#define MAX_MEASURE_NB 5
#define NAS_MAX_LENGTH 180
//Debug flags
//#define NAS_DEBUG_DC
//#define NAS_DEBUG_SEND
//#define NAS_DEBUG_RECEIVE
//#define NAS_DEBUG_CLASS
//#define NAS_DEBUG_GC
//#define NAS_DEBUG_DC_MEASURE
//#define NAS_DEBUG_TIMER
//#define NAS_DEBUG_DEVICE
//#define NAS_DEBUG_INTERRUPT
//#define NAS_DEBUG_TOOL
// Other flags
#define DEMO_3GSM
// General Constants
#define NAS_MTU 1500
#define NAS_TX_QUEUE_LEN 100
#define NAS_ADDR_LEN 8
#define NAS_INET6_ADDRSTRLEN 46
#define NAS_INET_ADDRSTRLEN 16
#define NAS_CX_MAX 32 //128 //Identical to RRC constant: no you cannot
/* increase to 128 without risking stack problems: KEEP ATTENTION TO COMPILATION WARNINGS */
//#define NAS_CX_MULTICAST_ALLNODE 2
#define NAS_RETRY_LIMIT_DEFAULT 5
#define NAS_MESSAGE_MAXLEN 5004
#define NAS_SIG_SRB3 3
#define NAS_SIG_SRB4 3 // not used yet
//peer-to-peer messages between NAS entities
#define NAS_CMD_OPEN_RB 1
//#define NAS_IID1_CONTROL 0x0
//#define NAS_IID2_CONTROL __constant_htonl(0xffffffff)
//#define NAS_STATE_IDLE 0
//#define NAS_STATE_CONNECTED 1
//#define NAS_STATE_ESTABLISHMENT_REQUEST 2
//#define NAS_STATE_ESTABLISHMENT_FAILURE 3
//#define NAS_STATE_RELEASE_FAILURE 4
#define NAS_CX_RELEASE_UNDEF_CAUSE 1
// MT+RG NAS States
#define NAS_IDLE 0x01
// Connection
#define NAS_CX_FACH 0x06
#define NAS_CX_DCH 0x0A
#define NAS_CX_RECEIVED 0x10
#define NAS_CX_CONNECTING 0x04
#define NAS_CX_RELEASING 0x08
#define NAS_CX_CONNECTING_FAILURE 0x14
#define NAS_CX_RELEASING_FAILURE 0x18
// Radio Bearers
#define NAS_RB_ESTABLISHING 0x24
#define NAS_RB_RELEASING 0x28
#define NAS_RB_DCH 0x2A
#define NAS_TIMER_ESTABLISHMENT_DEFAULT 12
#define NAS_TIMER_RELEASE_DEFAULT 2
#define NAS_TIMER_IDLE UINT_MAX
#define NAS_TIMER_TICK HZ
#define NAS_PDCPH_SIZE sizeof(struct pdcp_data_req_header_s)
#define NAS_IPV4_SIZE 20
#define NAS_IPV6_SIZE 40
#define NAS_DIRECTION_SEND 0
#define NAS_DIRECTION_RECEIVE 1
#define NAS_DIRECTION_FORWARD 2
// function number
#define NAS_FCT_DEL_SEND 1
#define NAS_FCT_QOS_SEND 2
#define NAS_FCT_DC_SEND 3
#define NAS_FCT_CTL_SEND 4
// type of IOCTL command
#define NAS_IOCTL_RRM 0x89F0
// Error cause
#define NAS_ERROR_ALREADYEXIST 1
#define NAS_ERROR_NOMEMORY 3
#define NAS_ERROR_NOTMT 9
#define NAS_ERROR_NOTRG 10
#define NAS_ERROR_NOTIDLE 11
#define NAS_ERROR_NOTCONNECTED 12
#define NAS_ERROR_NORB 14
#define NAS_ERROR_NOTCORRECTVALUE 32
#define NAS_ERROR_NOTCORRECTLCR 33
#define NAS_ERROR_NOTCORRECTDIR 34
#define NAS_ERROR_NOTCORRECTDSCP 35
#define NAS_ERROR_NOTCORRECTVERSION 36
#define NAS_ERROR_NOTCORRECTRABI 37
/**********************************************************/
/* Constants related with IP protocols */
/**********************************************************/
//#define NAS_PORT_CONTROL __constant_htons(0xc45)
//#define NAS_PORT_AUTHENTICATION __constant_htons(1811)
#define NAS_TRAFFICCLASS_MASK __constant_htonl(0x0fc00000)
// Network control codepoint 111000 + IP version 6
#define NAS_FLOWINFO_NCONTROL __constant_htonl(0x6e000000)
// network control codepoint 111000
#define NAS_DSCP_NCONTROL 56 //0x38
// default codepoint 1000000
#define NAS_DSCP_DEFAULT 64
#define NAS_DSCP_MAX 193
#define NAS_PROTOCOL_DEFAULT 0
#define NAS_PROTOCOL_TCP IPPROTO_TCP
#define NAS_PROTOCOL_UDP IPPROTO_UDP
#define NAS_PROTOCOL_ICMP4 IPPROTO_ICMP
#define NAS_PROTOCOL_ICMP6 IPPROTO_ICMPV6
#define NAS_PORT_DEFAULT __constant_htons(65535)
#define NAS_PORT_HTTP __constant_htons(80)
#define NAS_VERSION_DEFAULT 0
#define NAS_VERSION_4 4
#define NAS_VERSION_6 0 //?MW
#define NAS_DEFAULT_IPV4_ADDR 0
#define NAS_DEFAULT_IPV6_ADDR0 0
#define NAS_DEFAULT_IPV6_ADDR1 0
#define NAS_DEFAULT_IPV6_ADDR2 0
#define NAS_DEFAULT_IPV6_ADDR3 0
#define NAS_MPLS_VERSION_CODE 99
#define NB_INSTANCES_MAX 64 //16
#endif

View File

@@ -1,509 +0,0 @@
/*
* 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
*/
/*! \file device.c
* \brief Networking Device Driver for OpenAirInterface MESH
* \author navid.nikaein, yan.moret(no longer valid), michelle.wetterwald, raymond.knopp
* \company Eurecom
* \email: raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, michelle.wetterwald@eurecom.fr,
*/
/*******************************************************************************/
#include "constant.h"
#include "local.h"
#include "proto_extern.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/moduleparam.h>
#include <asm/io.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/delay.h>
#include <asm/unistd.h>
//#define DEBUG_DEVICE 1
//#define DEBUG_INTERRUPT 1
struct net_device *nasdev[NB_INSTANCES_MAX];
extern void nas_netlink_release(void);
extern int nas_netlink_init(void);
//int bytes_wrote;
//int bytes_read;
uint8_t NULL_IMEI[14]= {0x05, 0x04, 0x03, 0x01, 0x02 ,0x00, 0x00, 0x00, 0x05, 0x04, 0x03 ,0x00, 0x01, 0x08};
static unsigned int nas_IMEI[6]= {0x03, 0x01, 0x02 ,0x00, 0x00, 0x00}; // may change to char
static int m_arg=0;
static unsigned int nas_is_clusterhead=0;
int find_inst(struct net_device *dev)
{
int i;
for (i=0; i<NB_INSTANCES_MAX; i++)
if (nasdev[i] == dev)
return(i);
return(-1);
}
//---------------------------------------------------------------------------
// Called by ifconfig when the device is activated by ifconfig
int nas_open(struct net_device *dev)
{
//---------------------------------------------------------------------------
printk("OPEN: begin\n");
// MOD_INC_USE_COUNT;
// Address has already been set at init
/*
netif_start_queue(dev);
//
init_timer(&priv->timer);
(priv->timer).expires=jiffies+NAS_TIMER_TICK;
(priv->timer).data=0L;
(priv->timer).function=nas_mesh_timer;
// add_timer(&priv->timer);
//
*/
printk("OPEN: name = %s, end\n", dev->name);
return 0;
}
//---------------------------------------------------------------------------
// Called by ifconfig when the device is desactivated
int nas_stop(struct net_device *dev)
{
//---------------------------------------------------------------------------
struct nas_priv *priv = netdev_priv(dev);
printk("STOP: begin\n");
del_timer(&(priv->timer));
netif_stop_queue(dev);
// MOD_DEC_USE_COUNT;
printk("STOP: name = %s, end\n", dev->name);
return 0;
}
//---------------------------------------------------------------------------
void nas_teardown(struct net_device *dev)
{
//---------------------------------------------------------------------------
int cxi;
struct nas_priv *priv;
int inst;
if (dev) {
priv = netdev_priv(dev);
inst = find_inst(dev);
if (inst<0) {
printk("nas_teardown: ERROR, couldn't find instance\n");
}
printk("nas_teardown instance %d: begin\n",inst);
nas_CLASS_flush_rclassifier(priv);
for (cxi=0; cxi<NAS_CX_MAX; cxi++) {
nas_COMMON_flush_rb(priv->cx+cxi);
nas_CLASS_flush_sclassifier(priv->cx+cxi);
}
printk("nas_teardown: end\n");
} // check dev
else {
printk("nas_teardown: Device is null\n");
}
}
//---------------------------------------------------------------------------
int nas_set_config(struct net_device *dev, struct ifmap *map)
{
//---------------------------------------------------------------------------
printk("SET_CONFIG: begin\n");
if (dev->flags & IFF_UP)
return -EBUSY;
if (map->base_addr != dev->base_addr) {
printk(KERN_WARNING "SET_CONFIG: Can't change I/O address\n");
return -EOPNOTSUPP;
}
if (map->irq != dev->irq)
dev->irq = map->irq;
return 0;
}
//---------------------------------------------------------------------------
//
int nas_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
//---------------------------------------------------------------------------
// Start debug information
int inst;
if (dev)
inst = find_inst(dev);
else {
printk("nas_hard_start_xmit: ERROR, device is null\n");
return -1;
}
if (inst>=0) {
#ifdef DEBUG_DEVICE
printk("HARD_START_XMIT: inst %d, begin\n",inst);
#endif
if (!skb) {
printk("HARD_START_XMIT - input parameter skb is NULL \n");
return -1;
}
// End debug information
netif_stop_queue(dev);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) \
|| (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796 && RHEL_RELEASE_CODE != 2403)
netif_trans_update(dev);
#else
dev->trans_start = jiffies;
#endif
#ifdef DEBUG_DEVICE
printk("HARD_START_XMIT: step 1\n");
#endif
nas_CLASS_send(skb,inst);
#ifdef DEBUG_DEVICE
printk("HARD_START_XMIT: step 2\n");
#endif
// if (skb==NULL){
// printk("HARD_START_XMIT - parameter skb is NULL \n");
// return -1;
// }else
dev_kfree_skb(skb);
#ifdef DEBUG_DEVICE
printk("HARD_START_XMIT: step 3\n");
#endif
netif_wake_queue(dev);
#ifdef DEBUG_DEVICE
printk("HARD_START_XMIT: end\n");
#endif
} else {
printk("nas_hard_start_xmit: ERROR, couldn't find instnace\n");
return(-1);
}
return 0;
}
//---------------------------------------------------------------------------
struct net_device_stats *nas_get_stats(struct net_device *dev)
{
//---------------------------------------------------------------------------
// return &((struct nas_priv *)dev->priv)->stats;
struct nas_priv *priv = netdev_priv(dev);
return &priv->stats;
}
//---------------------------------------------------------------------------
int nas_change_mtu(struct net_device *dev, int mtu)
{
//---------------------------------------------------------------------------
printk("CHANGE_MTU: begin\n");
if ((mtu<50) || (mtu>1500))
return -EINVAL;
dev->mtu = mtu;
return 0;
}
//---------------------------------------------------------------------------
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
void nas_tx_timeout(struct net_device *dev, unsigned int txqueue)
#else
void nas_tx_timeout(struct net_device *dev)
#endif
{
//---------------------------------------------------------------------------
// Transmitter timeout, serious problems.
struct nas_priv *priv = netdev_priv(dev);
printk("TX_TIMEOUT: begin\n");
// (struct nas_priv *)(dev->priv)->stats.tx_errors++;
(priv->stats).tx_errors++;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) \
|| (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796 && RHEL_RELEASE_CODE != 2403)
netif_trans_update(dev);
#else
dev->trans_start = jiffies;
#endif
netif_wake_queue(dev);
printk("TX_TIMEOUT: transmit timed out %s\n",dev->name);
}
static const struct net_device_ops nasmesh_netdev_ops = {
.ndo_open = nas_open,
.ndo_stop = nas_stop,
.ndo_start_xmit = nas_hard_start_xmit,
.ndo_validate_addr = NULL,
.ndo_set_mac_address = NULL,
.ndo_set_config = nas_set_config,
.ndo_do_ioctl = nas_CTL_ioctl,
#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,11,0) \
|| (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1797 && RHEL_RELEASE_CODE != 2403)
.extended.ndo_change_mtu = nas_change_mtu,
#else
.ndo_change_mtu = nas_change_mtu,
#endif
.ndo_tx_timeout = nas_tx_timeout,
};
//---------------------------------------------------------------------------
// Initialisation of the network device
void nas_init(struct net_device *dev)
{
//---------------------------------------------------------------------------
uint8_t cxi, dscpi;
struct nas_priv *priv;
// int inst;
if (dev) {
priv = netdev_priv(dev);
//memset(dev->priv, 0, sizeof(struct nas_priv));
memset(priv, 0, sizeof(struct nas_priv));
// priv=(struct nas_priv *)(dev->priv);
priv=netdev_priv(dev);
//
dev->netdev_ops = &nasmesh_netdev_ops;
// dev->type = ARPHRD_EUROPENAIRMESH;
//dev->type = ARPHRD_ETHER;
// dev->features = NETIF_F_NO_CSUM;
dev->hard_header_len = 0;
dev->addr_len = NAS_ADDR_LEN;
dev->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP;
dev->tx_queue_len = NAS_TX_QUEUE_LEN;
dev->mtu = NAS_MTU;
//
// Initialize private structure
// priv->sap[NAS_GC_SAPI] = RRC_DEVICE_GC;
// priv->sap[NAS_NT_SAPI] = RRC_DEVICE_NT;
priv->sap[NAS_RAB_INPUT_SAPI] = PDCP2PDCP_USE_RT_FIFO;//QOS_DEVICE_CONVERSATIONAL_INPUT;
priv->sap[NAS_RAB_OUTPUT_SAPI] = NAS2PDCP_FIFO;//QOS_DEVICE_STREAMING_INPUT;
// priv->retry_limit=RETRY_LIMIT_DEFAULT;
// priv->timer_establishment=TIMER_ESTABLISHMENT_DEFAULT;
// priv->timer_release=TIMER_RELEASE_DEFAULT;
for (dscpi=0; dscpi<65; ++dscpi)
priv->rclassifier[dscpi]=NULL;
priv->nrclassifier=0;
//
for (cxi=0; cxi<NAS_CX_MAX; cxi++) {
#ifdef DEBUG_DEVICE
printk("INIT: init classifiers, state and timer for MT %u\n", cxi);
#endif
// priv->cx[cxi].sap[NAS_DC_INPUT_SAPI] = RRC_DEVICE_DC_INPUT0;
// priv->cx[cxi].sap[NAS_DC_OUTPUT_SAPI] = RRC_DEVICE_DC_OUTPUT0;
priv->cx[cxi].state=NAS_IDLE;
priv->cx[cxi].countimer=NAS_TIMER_IDLE;
priv->cx[cxi].retry=0;
priv->cx[cxi].lcr=cxi;
priv->cx[cxi].rb=NULL;
priv->cx[cxi].num_rb=0;
// initialisation of the classifier
for (dscpi=0; dscpi<65; ++dscpi) {
priv->cx[cxi].sclassifier[dscpi]=NULL;
priv->cx[cxi].fclassifier[dscpi]=NULL;
}
priv->cx[cxi].nsclassifier=0;
priv->cx[cxi].nfclassifier=0;
// initialisation of the IP address
// TOOL_imei2iid(IMEI, (uint8_t *)priv->cx[cxi].iid6);
priv->cx[cxi].iid4=0;
//
}
spin_lock_init(&priv->lock);
//this requires kernel patch for OAI driver: typically for RF/hard realtime emu experimentation
#ifdef ADDRCONF
#ifdef NETLINK
nas_TOOL_imei2iid(IMEI, dev->dev_addr);// IMEI to device address (for stateless autoconfiguration address)
nas_TOOL_imei2iid(IMEI, (uint8_t *)priv->cx[0].iid6);
#else
nas_TOOL_imei2iid((uint8_t *)nas_IMEI, dev->dev_addr); // IMEI to device address (for stateless autoconfiguration address)
nas_TOOL_imei2iid((uint8_t *)nas_IMEI, (uint8_t *)priv->cx[0].iid6);
#endif
// this is more appropriate for user space soft realtime emulation
#else
memcpy(dev->dev_addr,&nas_IMEI[0],8);
printk("Setting HW addr to : %X%X\n",*((unsigned int *)&dev->dev_addr[0]),*((unsigned int *)&dev->dev_addr[4]));
((unsigned char*)dev->dev_addr)[7] = (unsigned char)find_inst(dev);
memcpy((uint8_t *)priv->cx[0].iid6,&nas_IMEI[0],8);
printk("INIT: init IMEI to IID\n");
#endif
printk("INIT: end\n");
return;
} // instance value check
else {
printk("nas_init(): ERROR, Device is NULL!!\n");
return;
}
}
//---------------------------------------------------------------------------
int init_module (void)
{
//---------------------------------------------------------------------------
int err,inst;
struct nas_priv *priv;
char devicename[100];
// Initialize parameters shared with RRC
printk("Starting NASMESH, number of IMEI paramters %d, IMEI %X%X\n",m_arg,nas_IMEI[0],nas_IMEI[1]);
for (inst=0; inst<NB_INSTANCES_MAX; inst++) {
printk("[NAS][INIT] nasmesh_init_module: begin init instance %d\n",inst);
sprintf(devicename,"oai%d",inst);
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
nasdev[inst] = alloc_netdev(sizeof(struct nas_priv),devicename, nas_init);
#else
nasdev[inst] = alloc_netdev(sizeof(struct nas_priv),devicename, NET_NAME_PREDICTABLE, nas_init);
#endif
priv = netdev_priv(nasdev[inst]);
if (nasdev[inst]) {
nas_mesh_init(inst);
//memcpy(nasdev[inst]->dev_addr,&nas_IMEI[0],8);
nas_TOOL_imei2iid((uint8_t *)nas_IMEI, nasdev[inst]->dev_addr);// IMEI to device address (for stateless autoconfiguration address)
nas_TOOL_imei2iid((uint8_t *)nas_IMEI, (uint8_t *)priv->cx[0].iid6);
// TO HAVE DIFFERENT HW @
((unsigned char*)nasdev[inst]->dev_addr)[7] = ((unsigned char*)nasdev[inst]->dev_addr)[7] + (unsigned char)inst + 1;
printk("Setting HW addr for INST %d to : %X%X\n",inst,*((unsigned int *)&nasdev[inst]->dev_addr[0]),*((unsigned int *)&nasdev[inst]->dev_addr[4]));
}
err= register_netdev(nasdev[inst]);
if (err) {
printk("[NAS][INIT] nasmesh_init_module (inst %d): error %i registering device %s\n", inst,err, nasdev[inst]->name);
} else {
printk("nasmesh_init_module: registering device %s, ifindex = %d\n\n",nasdev[inst]->name, nasdev[inst]->ifindex);
}
}
if ((err=nas_netlink_init()) == -1)
printk("[NAS][INIT] NETLINK failed\n");
printk("[NAS][INIT] NETLINK INIT\n");
return err;
}
//---------------------------------------------------------------------------
void cleanup_module(void)
{
//---------------------------------------------------------------------------
int inst;
printk("[NAS][CLEANUP]nasmesh_cleanup_module: begin\n");
for (inst=0; inst<NB_INSTANCES_MAX; inst++) {
#ifdef DEBUG_DEVICE
printk("nasmesh_cleanup_module: unregister and free net device instance %d\n",inst);
#endif
unregister_netdev(nasdev[inst]);
nas_teardown(nasdev[inst]);
free_netdev(nasdev[inst]);
}
nas_netlink_release();
printk("nasmesh_cleanup_module: end\n");
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)
#define DRV_NAME "NASMESH"
#define DRV_VERSION "3.0.2"DRV_NAME
#define DRV_DESCRIPTION "OPENAIR MESH Device Driver"
#define DRV_COPYRIGHT "-Copyright(c) GNU GPL Eurecom 2009"
#define DRV_AUTHOR "Raymond Knopp, and Navid Nikaein: <firstname.name@eurecom.fr>"DRV_COPYRIGHT
module_param_array(nas_IMEI,uint,&m_arg,0444);
MODULE_PARM_DESC(nas_IMEI,"The IMEI Hardware address (64-bit, decimal nibbles)");
module_param(nas_is_clusterhead,uint,0444);
MODULE_PARM_DESC(nas_is_clusterhead,"The Clusterhead Indicator");
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,1)
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_AUTHOR(DRV_AUTHOR);
#endif
#endif
/*
//---------------------------------------------------------------------------
//module_init(init_nasmesh);
//module_exit(exit_nasmesh);
//---------------------------------------------------------------------------
*/

View File

@@ -1,860 +0,0 @@
/*
* 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
*/
#include "local.h"
#include "ioctl.h"
#include "proto_extern.h"
//#include <linux/in.h>
#include <asm/uaccess.h>
#include <asm/checksum.h>
#include <asm/uaccess.h>
// Statistic
//---------------------------------------------------------------------------
void nas_set_msg_statistic_reply(struct nas_msg_statistic_reply *msgrep,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
msgrep->rx_packets=priv->stats.rx_packets;
msgrep->tx_packets=priv->stats.tx_packets;
msgrep->rx_bytes=priv->stats.rx_bytes;
msgrep->tx_bytes=priv->stats.tx_bytes;
msgrep->rx_errors=priv->stats.rx_errors;
msgrep->tx_errors=priv->stats.tx_errors;
msgrep->rx_dropped=priv->stats.rx_dropped;
msgrep->tx_dropped=priv->stats.tx_dropped;
}
//---------------------------------------------------------------------------
int nas_ioCTL_statistic_request(struct nas_ioctl *gifr,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct nas_msg_statistic_reply msgrep;
printk("NAS_IOCTL_STATISTIC: stat requested\n");
nas_set_msg_statistic_reply(&msgrep,priv);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("NAS_IOCTL_STATISTIC: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Connections List
//---------------------------------------------------------------------------
void nas_set_msg_cx_list_reply(uint8_t *msgrep,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct cx_entity *cx;
nasLocalConnectionRef_t lcr;
struct nas_msg_cx_list_reply *list;
msgrep[0]=NAS_CX_MAX;
list=(struct nas_msg_cx_list_reply *)(msgrep+1);
for(lcr=0; lcr<NAS_CX_MAX; ++lcr) {
cx=nas_COMMON_search_cx(lcr,priv);
list[lcr].lcr=lcr;
list[lcr].state=cx->state;
list[lcr].cellid=cx->cellid;
list[lcr].iid4=cx->iid4;
list[lcr].iid6[0]=cx->iid6[0];
list[lcr].iid6[1]=cx->iid6[1];
list[lcr].num_rb=cx->num_rb;
list[lcr].nsclassifier=cx->nsclassifier;
printk("NAS_SET_MSG_CX_LIST_REPLY: nsc=%u\n",cx->nsclassifier);
}
}
//---------------------------------------------------------------------------
int nas_ioCTL_cx_list_request(struct nas_ioctl *gifr,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
uint8_t msgrep[NAS_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1];
printk("NAS_IOCTL_CX_LIST: connection list requested\n");
nas_set_msg_cx_list_reply(msgrep,priv);
if (copy_to_user(gifr->msg, msgrep, NAS_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1)) {
printk("NAS_IOCTL_CX_LIST: copy_to_user failure\n");
return -EFAULT;
}
printk("NAS_IOCTL_CX_LIST: end\n");
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Connection Establishment
//---------------------------------------------------------------------------
void nas_set_msg_cx_establishment_reply(struct nas_msg_cx_establishment_reply *msgrep,
struct nas_msg_cx_establishment_request *msgreq,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct cx_entity *cx;
cx=nas_COMMON_search_cx(msgreq->lcr,priv);
if (cx!=NULL) {
cx->cellid=msgreq->cellid;
msgrep->status=nas_mesh_DC_send_cx_establish_request(cx,priv);
} else
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
}
//---------------------------------------------------------------------------
int nas_ioCTL_cx_establishment_request(struct nas_ioctl *gifr,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct nas_msg_cx_establishment_request msgreq;
struct nas_msg_cx_establishment_reply msgrep;
printk("NAS_IOCTL_ESTABLISHMENT: connection establishment requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("NAS_IOCTL_CX_ESTABLISHMENT: copy_from_user failure\n");
return -EFAULT;
}
nas_set_msg_cx_establishment_reply(&msgrep, &msgreq,priv);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("NAS_IOCTL_CX_ESTABLISHMENT: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Connection Release
//---------------------------------------------------------------------------
void nas_set_msg_cx_release_reply(struct nas_msg_cx_release_reply *msgrep,
struct nas_msg_cx_release_request *msgreq,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct cx_entity *cx;
cx=nas_COMMON_search_cx(msgreq->lcr,priv);
if (cx!=NULL)
msgrep->status=nas_mesh_DC_send_cx_release_request(cx,priv);
else
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
}
//---------------------------------------------------------------------------
// Request the release of a connection
int nas_ioCTL_cx_release_request(struct nas_ioctl *gifr,struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct nas_msg_cx_release_request msgreq;
struct nas_msg_cx_release_reply msgrep;
printk("NAS_IOCTL_CX_RELEASE: connection release requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("NAS_IOCTL_CX_RELEASE: copy_from_user failure\n");
return -EFAULT;
}
nas_set_msg_cx_release_reply(&msgrep, &msgreq,priv);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("NAS_IOCTL_CX_RELEASE: copy_to_user failure\n");
return -EFAULT;
}
printk("NAS_IOCTL_CX_RELEASE: end\n");
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Radio Bearer List
//---------------------------------------------------------------------------
void nas_set_msg_rb_list_reply(uint8_t *msgrep,
struct nas_msg_rb_list_request *msgreq,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct cx_entity *cx;
cx=nas_COMMON_search_cx(msgreq->lcr,priv);
if (cx!=NULL) {
uint8_t rbi;
struct rb_entity *rb;
struct nas_msg_rb_list_reply *list;
if (cx->num_rb > NAS_LIST_RB_MAX)
msgrep[0] = NAS_LIST_RB_MAX;
else
msgrep[0] = cx->num_rb;
list=(struct nas_msg_rb_list_reply *)(msgrep+1);
for (rb=cx->rb, rbi=0; (rb!=NULL)&&(rbi<msgrep[0]); rb=rb->next, ++rbi) {
list[rbi].state=rb->state;
list[rbi].rab_id=rb->rab_id;
list[rbi].sapi=rb->sapi;
list[rbi].qos=rb->qos;
}
} else
msgrep[0]=0;
}
//---------------------------------------------------------------------------
int nas_ioCTL_rb_list_request(struct nas_ioctl *gifr,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
uint8_t msgrep[NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1];
struct nas_msg_rb_list_request msgreq;
printk("NAS_IOCTL_RB_LIST: Radio Bearer list requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("NAS_IOCTL_RB_LIST: copy_from_user failure\n");
return -EFAULT;
}
nas_set_msg_rb_list_reply(msgrep, &msgreq,priv);
if (copy_to_user(gifr->msg, msgrep, NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1)) {
printk("NAS_IOCTL_RB_LIST: copy_to_user failure\n");
return -EFAULT;
}
printk("NAS_IOCTL_CX_LIST: end\n");
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Radio Bearer Establishment
//---------------------------------------------------------------------------
void nas_set_msg_rb_establishment_reply(struct nas_msg_rb_establishment_reply *msgrep,
struct nas_msg_rb_establishment_request *msgreq,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
// if ((msgreq->rab_id<3)||(msgreq->rab_id>127))
if ((msgreq->rab_id<1)||(msgreq->rab_id>MAX_RABS)) // navid : increase the number
msgrep->status=-NAS_ERROR_NOTCORRECTRABI;
else {
struct cx_entity *cx;
cx=nas_COMMON_search_cx(msgreq->lcr,priv);
if (cx==NULL)
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
else {
struct rb_entity *rb;
rb=nas_COMMON_add_rb(cx, msgreq->rab_id, msgreq->qos);
if (rb!=NULL) {
// rb->cnxid = msgreq->cnxid;
// msgrep->status=nas_rg_DC_send_rb_establish_request(cx, rb);
} else
msgrep->status=-NAS_ERROR_NOMEMORY;
// msgrep->cnxid = msgreq->cnxid;
}
}
}
//---------------------------------------------------------------------------
int nas_ioCTL_rb_establishment_request(struct nas_ioctl *gifr,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct nas_msg_rb_establishment_request msgreq;
struct nas_msg_rb_establishment_reply msgrep;
printk("NAS_IOCTL_RB_ESTABLISHMENT: Radio bearer establishment requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("NAS_IOCTL_RB_ESTABLISHMENT: copy_from_user failure\n");
return -EFAULT;
}
nas_set_msg_rb_establishment_reply(&msgrep, &msgreq,priv);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("NAS_IOCTL_RB_ESTABLISHMENT: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Radio Bearer Release
//---------------------------------------------------------------------------
void nas_set_msg_rb_release_reply(struct nas_msg_rb_release_reply *msgrep,
struct nas_msg_rb_release_request *msgreq,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
if (msgreq->lcr<NAS_CX_MAX) {
struct rb_entity *rb;
struct cx_entity *cx;
cx=nas_COMMON_search_cx(msgreq->lcr,priv);
rb=nas_COMMON_search_rb(cx, msgreq->rab_id);
if (rb!=NULL) {
//msgrep->status=nas_rg_DC_send_rb_release_request(cx, rb);
} else
msgrep->status=-NAS_ERROR_NOTCONNECTED;
// msgrep->cnxid = msgreq->cnxid;
} else
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
}
//---------------------------------------------------------------------------
int nas_ioCTL_rb_release_request(
struct nas_ioctl *gifr,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct nas_msg_rb_release_request msgreq;
struct nas_msg_rb_release_reply msgrep;
printk("NAS_IOCTL_RB_RELEASE: Radio bearer release requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("NAS_IOCTL_RB_RELEASE: copy_from_user failure\n");
return -EFAULT;
}
nas_set_msg_rb_release_reply(&msgrep, &msgreq, priv);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("NAS_IOCTL_RB_RELEASE: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Classifier List
//---------------------------------------------------------------------------
void nas_set_msg_class_list_reply(
uint8_t *msgrep,
struct nas_msg_class_list_request *msgreq,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct cx_entity *cx;
struct classifier_entity *gc;
struct nas_msg_class_list_reply *list;
uint8_t cli;
list=(struct nas_msg_class_list_reply *)(msgrep+1);
switch(msgreq->dir) {
case NAS_DIRECTION_SEND:
cx=nas_COMMON_search_cx(msgreq->lcr,priv);
if (cx==NULL) {
msgrep[0]=0;
return;
}
gc=cx->sclassifier[msgreq->dscp];
break;
case NAS_DIRECTION_RECEIVE:
cx=NULL;
gc=priv->rclassifier[msgreq->dscp];
break;
default:
cx=NULL;
msgrep[0]=0;
return;
}
for (cli=0; (gc!=NULL)&&(cli<NAS_LIST_CLASS_MAX); gc=gc->next, ++cli) {
list[cli].classref=gc->classref;
list[cli].lcr=msgreq->lcr;
list[cli].dir=msgreq->dir;
list[cli].dscp=msgreq->dscp;
list[cli].rab_id=gc->rab_id;
list[cli].version=gc->version;
switch(gc->version) {
case 4:
list[cli].saddr.ipv4 = gc->saddr.ipv4;
list[cli].daddr.ipv4 = gc->daddr.ipv4;
break;
case 6:
list[cli].saddr.ipv6 = gc->saddr.ipv6;
list[cli].daddr.ipv6 = gc->daddr.ipv6;
break;
}
list[cli].protocol=gc->protocol;
list[cli].sport=ntohs(gc->sport);
list[cli].dport=ntohs(gc->dport);
list[cli].splen=gc->splen;
list[cli].dplen=gc->dplen;
list[cli].fct=nas_TOOL_invfct(gc);
}
msgrep[0]=cli;
}
//---------------------------------------------------------------------------
int nas_ioCTL_class_list_request(
struct nas_ioctl *gifr,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
uint8_t msgrep[NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1];
struct nas_msg_class_list_request msgreq;
printk("NAS_IOCTL_CLASS_LIST: classifier list requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("NAS_IOCTL_CLASS_LIST: copy_from_user failure\n");
return -EFAULT;
}
nas_set_msg_class_list_reply(msgrep, &msgreq,priv);
if (copy_to_user(gifr->msg, msgrep, NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1)) {
printk("NAS_IOCTL_CLASS_LIST: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Request the addition of a classifier rule
//---------------------------------------------------------------------------
void nas_set_msg_class_add_reply(
struct nas_msg_class_add_reply *msgrep,
struct nas_msg_class_add_request *msgreq,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct classifier_entity *gc,*gc2;
unsigned char *saddr,*daddr;
unsigned int *saddr32,*daddr32;
printk("[NAS][CLASS] nas_set_msg_class_add_reply\n");
if (msgreq->dscp>NAS_DSCP_MAX) {
printk("NAS_SET_MSG_CLASS_ADD_REPLY: Incoherent parameter value\n");
msgrep->status=-NAS_ERROR_NOTCORRECTDSCP;
return;
}
if (msgreq->dir==NAS_DIRECTION_SEND) {
struct cx_entity *cx;
cx=nas_COMMON_search_cx(msgreq->lcr,priv);
if (cx!=NULL) {
printk("NAS_SET_MSG_CLASS_ADD_REPLY: DSCP/EXP %d, Classref %d, RB %u\n", msgreq->dscp, msgreq->classref,msgreq->rab_id );
gc=nas_CLASS_add_sclassifier(cx, msgreq->dscp, msgreq->classref);
printk("NAS_SET_MSG_CLASS_ADD_REPLY: %p %p\n" , msgreq, gc);
if (gc==NULL) {
msgrep->status=-NAS_ERROR_NOMEMORY;
return;
}
} else {
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
return;
}
gc->rab_id=msgreq->rab_id;
gc->rb=nas_COMMON_search_rb(cx, gc->rab_id);
printk("NAS_SET_MSG_CLASS_ADD_REPLY: gc_rb %p %u \n", gc->rb, gc->rab_id);
} else {
if (msgreq->dir==NAS_DIRECTION_RECEIVE) {
gc=nas_CLASS_add_rclassifier(msgreq->dscp,
msgreq->classref,
priv);
if (gc==NULL) {
msgrep->status=-NAS_ERROR_NOMEMORY;
return;
}
gc->rab_id=msgreq->rab_id;
} else {
msgrep->status=-NAS_ERROR_NOTCORRECTDIR;
return;
}
for (gc2 = priv->rclassifier[msgreq->dscp]; gc2!=NULL ; gc2 = gc2->next)
printk("[NAS][CLASS] Add Receive Classifier dscp %d: rab_id %d (%p,next %p)\n",msgreq->dscp,gc2->rab_id,gc2,gc2->next);
}
printk("[NAS][CLASS] Getting addresses ...\n");
nas_TOOL_fct(gc, msgreq->fct);
gc->version=msgreq->version;
switch(gc->version) {
case 4:
gc->saddr.ipv4=msgreq->saddr.ipv4;
gc->daddr.ipv4=msgreq->daddr.ipv4;
// #ifdef NAS_CLASS_DEBUG
saddr = (unsigned char *)&gc->saddr.ipv4;
daddr = (unsigned char *)&gc->daddr.ipv4;
printk("[NAS][CLASS] Adding IPv4 %d.%d.%d.%d -> %d.%d.%d.%d\n",
saddr[0],saddr[1],saddr[2],saddr[3],
daddr[0],daddr[1],daddr[2],daddr[3]);
//#endif
gc->splen=msgreq->splen;
gc->dplen=msgreq->dplen;
break;
case 6:
memcpy(&gc->saddr.ipv6,&msgreq->saddr.ipv6,16);
memcpy(&gc->daddr.ipv6,&msgreq->daddr.ipv6,16);
saddr32 = (unsigned int *)&gc->saddr.ipv6;
daddr32 = (unsigned int *)&gc->daddr.ipv6;
printk("[NAS][CLASS] Adding IPv6 %X:%X:%X:%X -> %X.%X.%X.%X\n",
saddr32[0],saddr32[1],saddr32[2],saddr32[3],
daddr32[0],daddr32[1],daddr32[2],daddr32[3]);
gc->splen=msgreq->splen;
gc->dplen=msgreq->dplen;
break;
case NAS_MPLS_VERSION_CODE:
printk("[NAS][CLASS] Adding MPLS label %d with exp %d\n",
msgreq->daddr.mpls_label,msgreq->dscp);
gc->daddr.mpls_label = msgreq->daddr.mpls_label;
break;
case 0:
gc->saddr.ipv6.s6_addr32[0]=0;
gc->daddr.ipv6.s6_addr32[1]=0;
gc->saddr.ipv6.s6_addr32[2]=0;
gc->daddr.ipv6.s6_addr32[3]=0;
gc->splen=0;
gc->dplen=0;
break;
default:
msgrep->status=-NAS_ERROR_NOTCORRECTVERSION;
kfree(gc);
return;
}
gc->protocol=msgreq->protocol;
gc->protocol_message_type=msgreq->protocol_message_type;
gc->sport=htons(msgreq->sport);
gc->dport=htons(msgreq->dport);
msgrep->status=0;
}
//---------------------------------------------------------------------------
int nas_ioCTL_class_add_request(struct nas_ioctl *gifr,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct nas_msg_class_add_request msgreq;
struct nas_msg_class_add_reply msgrep;
printk("NAS_IOCTL_CLASS_ADD: Add classifier components requested\n");
printk("NAS_IOCTL_CLASS_ADD: size of gifr msg %zd\n", sizeof(gifr->msg));
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("NAS_IOCTL_CLASS_ADD: copy_from_user failure\n");
return -EFAULT;
}
nas_set_msg_class_add_reply(&msgrep, &msgreq,priv);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("NAS_IOCTL_CLASS_ADD: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Request the deletion of a classifier rule
//---------------------------------------------------------------------------
void nas_set_msg_class_del_reply(struct nas_msg_class_del_reply *msgrep,
struct nas_msg_class_del_request *msgreq,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
if (msgreq->dscp>NAS_DSCP_DEFAULT) {
printk("NAS_SET_MSG_CLASS_DEL_REPLY: Incoherent parameter value\n");
msgrep->status=-NAS_ERROR_NOTCORRECTDSCP;
return;
}
if (msgreq->dir==NAS_DIRECTION_SEND) {
struct cx_entity *cx;
cx=nas_COMMON_search_cx(msgreq->lcr,priv);
if (cx!=NULL)
nas_CLASS_del_sclassifier(cx, msgreq->dscp, msgreq->classref);
else {
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
return;
}
} else {
if (msgreq->dir==NAS_DIRECTION_RECEIVE)
nas_CLASS_del_rclassifier(msgreq->dscp, msgreq->classref,priv);
else {
msgrep->status=-NAS_ERROR_NOTCORRECTDIR;
return;
}
}
msgrep->status=0;
}
//---------------------------------------------------------------------------
int nas_ioCTL_class_del_request(struct nas_ioctl *gifr,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct nas_msg_class_del_request msgreq;
struct nas_msg_class_del_reply msgrep;
printk("NAS_IOCTL_CLASS_DEL: Del classifier components requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("NAS_IOCTL_CLASS_DEL: copy_from_user failure\n");
return -EFAULT;
}
nas_set_msg_class_del_reply(&msgrep, &msgreq,priv);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("NAS_IOCTL_CLASS_DEL: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Measurement
// Messages for Measurement transfer
//---------------------------------------------------------------------------
void nas_set_msg_measure_reply(struct nas_msg_measure_reply *msgrep, struct nas_msg_measure_request *msgreq,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct cx_entity *cx;
int lcr=0; // Temp lcr->mt =0
int i;
cx=nas_COMMON_search_cx(lcr,priv);
if (cx!=NULL) {
msgrep->num_cells = cx->num_measures;
for (i=0; i<cx->num_measures; i++) {
msgrep-> measures[i].cell_id = cx->meas_cell_id[i];
msgrep-> measures[i].level = cx->meas_level[i];
msgrep-> measures[i].provider_id = cx->provider_id[i];
}
msgrep->signal_lost_flag = 0;
}
}
//---------------------------------------------------------------------------
int nas_ioCTL_measure_request(struct nas_ioctl *gifr,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct nas_msg_measure_request msgreq;
struct nas_msg_measure_reply msgrep;
printk("NAS_IOCTL_MEASURE: Measurement requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("NAS_IOCTL_MEASURE: copy_from_user failure\n");
return -EFAULT;
}
nas_set_msg_measure_reply(&msgrep, &msgreq,priv);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("NAS_IOCTL_MEASURE: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// IMEI
// Messages for IMEI transfer
//---------------------------------------------------------------------------
void nas_set_msg_imei_reply(struct nas_msg_l2id_reply *msgrep,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct cx_entity *cx;
int lcr=0; // Temp lcr->mt =0
cx=nas_COMMON_search_cx(lcr,priv);
if (cx!=NULL) {
msgrep->l2id[0] = cx->iid6[0];
msgrep->l2id[1] = cx->iid6[1];
}
}
//---------------------------------------------------------------------------
int nas_ioCTL_imei_request(struct nas_ioctl *gifr,
struct nas_priv *priv)
{
//---------------------------------------------------------------------------
struct nas_msg_l2id_reply msgrep;
printk("NAS_IOCTL_IMEI: IMEI requested\n");
nas_set_msg_imei_reply(&msgrep,priv);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("NAS_IOCTL_IMEI: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// IOCTL command
//---------------------------------------------------------------------------
int nas_CTL_ioctl(struct net_device *dev,
struct ifreq *ifr,
int cmd)
{
//---------------------------------------------------------------------------
struct nas_ioctl *gifr;
struct nas_priv *priv=netdev_priv(dev);
int r;
// printk("NAS_CTL_IOCTL: begin ioctl for instance %d\n",find_inst(dev));
switch(cmd) {
case NAS_IOCTL_RRM:
gifr=(struct nas_ioctl *)ifr;
switch(gifr->type) {
case NAS_MSG_STATISTIC_REQUEST:
r=nas_ioCTL_statistic_request(gifr,priv);
break;
case NAS_MSG_CX_ESTABLISHMENT_REQUEST:
r=nas_ioCTL_cx_establishment_request(gifr,priv);
break;
case NAS_MSG_CX_RELEASE_REQUEST:
r=nas_ioCTL_cx_release_request(gifr,priv);
break;
case NAS_MSG_CX_LIST_REQUEST:
r=nas_ioCTL_cx_list_request(gifr,priv);
break;
case NAS_MSG_RB_ESTABLISHMENT_REQUEST:
r=nas_ioCTL_rb_establishment_request(gifr,priv);
break;
case NAS_MSG_RB_RELEASE_REQUEST:
r= nas_ioCTL_rb_release_request(gifr,priv);
break;
case NAS_MSG_RB_LIST_REQUEST:
r=nas_ioCTL_rb_list_request(gifr,priv);
break;
case NAS_MSG_CLASS_ADD_REQUEST:
r=nas_ioCTL_class_add_request(gifr,priv);
break;
case NAS_MSG_CLASS_LIST_REQUEST:
r=nas_ioCTL_class_list_request(gifr,priv);
break;
case NAS_MSG_CLASS_DEL_REQUEST:
r=nas_ioCTL_class_del_request(gifr,priv);
break;
case NAS_MSG_MEAS_REQUEST:
r=nas_ioCTL_measure_request(gifr,priv);
break;
case NAS_MSG_IMEI_REQUEST:
r=nas_ioCTL_imei_request(gifr,priv);
break;
default:
// printk("NAS_IOCTL_RRM: unkwon request type, type=%x\n", gifr->type);
r=-EFAULT;
}
break;
default:
// printk("NAS_CTL_IOCTL: Unknown ioctl command, cmd=%x\n", cmd);
r=-EFAULT;
}
// printk("NAS_CTL_IOCTL: end\n");
return r;
}
//---------------------------------------------------------------------------
void nas_CTL_send(struct sk_buff *skb,
struct cx_entity *cx,
struct classifier_entity *gc, int inst, struct nas_priv *gpriv)
{
//---------------------------------------------------------------------------
printk("NAS_CTL_SEND - void \n");
}

View File

@@ -1,245 +0,0 @@
/*
* 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
*/
#ifndef NAS_CTL_H
#define NAS_CTL_H
#include <asm/byteorder.h>
#include <asm/types.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/if.h>
//#include <linux/ipv6.h>
#define NAS_MSG_MAXLEN 1100/// change???
// type of CTL message
#define NAS_MSG_STATISTIC_REQUEST 1
#define NAS_MSG_STATISTIC_REPLY 2
#define NAS_MSG_ECHO_REQUEST 3
#define NAS_MSG_ECHO_REPLY 4
#define NAS_MSG_CX_ESTABLISHMENT_REQUEST 5
#define NAS_MSG_CX_ESTABLISHMENT_REPLY 6
#define NAS_MSG_CX_RELEASE_REQUEST 7
#define NAS_MSG_CX_RELEASE_REPLY 8
#define NAS_MSG_CX_LIST_REQUEST 9
#define NAS_MSG_CX_LIST_REPLY 10
#define NAS_MSG_RB_ESTABLISHMENT_REQUEST 11
#define NAS_MSG_RB_ESTABLISHMENT_REPLY 12
#define NAS_MSG_RB_RELEASE_REQUEST 13
#define NAS_MSG_RB_RELEASE_REPLY 14
#define NAS_MSG_RB_LIST_REQUEST 15
#define NAS_MSG_RB_LIST_REPLY 16
#define NAS_MSG_CLASS_ADD_REQUEST 17
#define NAS_MSG_CLASS_ADD_REPLY 18
#define NAS_MSG_CLASS_DEL_REQUEST 19
#define NAS_MSG_CLASS_DEL_REPLY 20
#define NAS_MSG_CLASS_LIST_REQUEST 21
#define NAS_MSG_CLASS_LIST_REPLY 22
#define NAS_MSG_MEAS_REQUEST 23
#define NAS_MSG_MEAS_REPLY 24
#define NAS_MSG_IMEI_REQUEST 25
#define NAS_MSG_IMEI_REPLY 26
// Max number of entry of a message list
#define NAS_LIST_CX_MAX 32
#define NAS_LIST_RB_MAX 32
#define NAS_LIST_CLASS_MAX 16 // 32 is too high!!:
/* risk of stack problems: KEEP ATTENTION TO COMPILATION WARNINGS */
typedef unsigned short nasMsgType_t;
struct nas_ioctl {
char name[IFNAMSIZ];
nasMsgType_t type;
char *msg;
};
struct nas_msg_statistic_reply {
unsigned int rx_packets;
unsigned int tx_packets;
unsigned int rx_bytes;
unsigned int tx_bytes;
unsigned int rx_errors;
unsigned int tx_errors;
unsigned int rx_dropped;
unsigned int tx_dropped;
};
struct nas_msg_cx_list_reply {
nasLocalConnectionRef_t lcr; // Local Connection reference
unsigned char state;
nasCellID_t cellid; // cell identification
unsigned int iid6[2]; // IPv6 interface identification
unsigned char iid4; // IPv4 interface identification
unsigned short num_rb;
unsigned short nsclassifier;
};
struct nas_msg_cx_establishment_reply {
int status;
};
struct nas_msg_cx_establishment_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
nasCellID_t cellid; // Cell identification
};
struct nas_msg_cx_release_reply {
int status;
};
struct nas_msg_cx_release_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
};
struct nas_msg_rb_list_reply {
nasRadioBearerId_t rab_id;
nasSapId_t sapi;
nasQoSTrafficClass_t qos;
unsigned char state;
};
struct nas_msg_rb_list_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
};
struct nas_msg_rb_establishment_reply {
int status;
};
struct nas_msg_rb_establishment_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
nasRadioBearerId_t rab_id;
nasQoSTrafficClass_t qos;
};
struct nas_msg_rb_release_reply {
int status;
};
struct nas_msg_rb_release_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
nasRadioBearerId_t rab_id;
};
/*
struct saddr {
struct in6_addr ipv6;
unsigned int ipv4;
};
struct daddr {
struct in6_addr ipv6;
unsigned int ipv4;
unsigned int mpls_label;
};
*/
struct nas_msg_class_add_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
nasRadioBearerId_t rab_id;
nasRadioBearerId_t rab_id_rx;
unsigned char dir; // direction (send or receive, forward)
unsigned char dscp; // codepoint
unsigned char fct;
unsigned short classref;
unsigned char version;
//struct daddr daddr;
//struct saddr saddr;
unsigned char splen; // prefix length
union {
struct in6_addr ipv6;
// begin navid
//in_addr_t ipv4;
unsigned int ipv4;
//end navid
unsigned int mpls_label;
} daddr; // IP destination address
union {
struct in6_addr ipv6;
// begin navid
//in_addr_t ipv4;
unsigned int ipv4;
//end navid
} saddr; // IP source address
unsigned char dplen; // prefix length
unsigned char protocol; //!< transport layer protocol type (ANY,TCP,UDP,ICMPv4,ICMPv6)
unsigned char protocol_message_type; //!< transport layer protocol message (ROUTER_ADV, ROUTER_SOLL, etc.)
unsigned short sport; //!< source port
unsigned short dport; //!< destination port
};
struct nas_msg_class_add_reply {
int status;
};
struct nas_msg_class_del_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
unsigned char dir; // direction (send or receive)
unsigned char dscp; // codepoint
unsigned short classref;
};
struct nas_msg_class_del_reply {
int status;
};
#define nas_msg_class_list_reply nas_msg_class_add_request
struct nas_msg_class_list_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
unsigned char dir;
unsigned char dscp;
};
// Messages for Measurement transfer - MW 01/04/2005
typedef unsigned int nioctlProviderId_t;
typedef unsigned short nioctlSignalLoss_t;
typedef struct nioctlMeasures {
nasCellID_t cell_id;
nasSigLevel_t level;
nioctlProviderId_t provider_id;
} nioctlMeasures_t;
struct nas_msg_measure_request {
nasNumRGsMeas_t num_cells;
nasCellID_t cellid[MAX_MEASURE_NB]; // Cell identification
unsigned short num_providers;
nioctlProviderId_t provider_id[MAX_MEASURE_NB]; // Provider identification
};
struct nas_msg_measure_reply {
nasNumRGsMeas_t num_cells;
nioctlMeasures_t measures[MAX_MEASURE_NB];
nioctlSignalLoss_t signal_lost_flag;
};
// Messages for Measurement transfer - MW 01/04/2005
typedef unsigned int nioctlL2Id_t[2];
struct nas_msg_l2id_reply {
nioctlL2Id_t l2id;
};
#endif

View File

@@ -1,181 +0,0 @@
/*
* 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
*/
/***************************************************************************
local.h - description
-------------------
copyright : (C) 2002 by Eurecom
email : navid.nikaein@eurecom.fr
lionel.gauthier@eurecom.fr
knopp@eurecom.fr
***************************************************************************
***************************************************************************/
#ifndef LOCAL_H
#define LOCAL_H
#include <linux/if_arp.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/ipv6.h>
#include <linux/ip.h>
#include <linux/sysctl.h>
#include <linux/timer.h>
#include <linux/unistd.h>
#include <asm/param.h>
//#include <sys/sysctl.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
#include <linux/in.h>
#include <net/ndisc.h>
//#include "rrc_nas_primitives.h"
//#include "rrc_sap.h"
#define PDCP2PDCP_USE_RT_FIFO 21
#define NAS2PDCP_FIFO 22
#include "constant.h"
#include "sap.h"
#include "rrc_nas_primitives.h"
#include "common/platform_types.h"
struct rb_entity {
nasRadioBearerId_t rab_id;
nasSapId_t sapi;
nasQoSTrafficClass_t qos;
uint8_t state;
uint8_t retry;
uint32_t countimer;
struct rb_entity *next;
};
struct cx_entity {
int sap[NAS_SAPI_CX_MAX];
uint8_t state; // state of the connection
nasLocalConnectionRef_t lcr; // Local connection reference
nasCellID_t cellid; // cell identification
uint32_t countimer; // timeout's counter
uint8_t retry; // number of retransmission
struct classifier_entity *sclassifier[NAS_DSCP_MAX]; // send classifier;
struct classifier_entity *fclassifier[NAS_DSCP_MAX]; // send classifier;
uint16_t nsclassifier;
uint16_t nfclassifier;
uint32_t iid6[2]; // IPv6 interface identification
uint8_t iid4; // IPv4 interface identification
struct rb_entity *rb;
uint16_t num_rb;
int lastRRCprimitive;
//measures
int req_prov_id[MAX_MEASURE_NB];
int num_measures;
int meas_cell_id[MAX_MEASURE_NB];
int meas_level[MAX_MEASURE_NB];
int provider_id[MAX_MEASURE_NB];
};
//#define NAS_RETRY_LIMIT_DEFAULT 5
struct nas_priv {
int irq;
struct timer_list timer;
spinlock_t lock;
struct net_device_stats stats;
uint8_t retry_limit;
uint32_t timer_establishment;
uint32_t timer_release;
struct cx_entity cx[NAS_CX_MAX];
struct classifier_entity *rclassifier[NAS_DSCP_MAX]; // receive classifier
uint16_t nrclassifier;
int sap[NAS_SAPI_MAX];
struct sock *nl_sk;
uint8_t nlmsg[NAS_MAX_LENGTH+sizeof(struct nlmsghdr)];
uint8_t xbuffer[NAS_MAX_LENGTH]; // transmition buffer
uint8_t rbuffer[NAS_MAX_LENGTH]; // reception buffer
};
struct classifier_entity {
uint32_t classref;
struct classifier_entity *next;
uint8_t version;
union {
struct in6_addr ipv6;
uint32_t ipv4;
} saddr; // IP source address
uint8_t splen; // prefix length
union {
struct in6_addr ipv6;
uint32_t ipv4;
unsigned int mpls_label;
} daddr; // IP destination address
uint8_t dplen; // prefix length
uint8_t protocol; // high layer protocol type
unsigned char protocol_message_type;
uint16_t sport; // source port
uint16_t dport; // destination port
struct rb_entity *rb; //pointer to rb_entity for sending function or receiving in case of forwarding rule
struct rb_entity *rb_rx; //pointer to rb_entity for receiving (in case of forwarding rule)
nasRadioBearerId_t rab_id; // RAB identification for sending
nasRadioBearerId_t rab_id_rx; // RAB identification for receiving (in case of forwarding rule)
void (*fct)(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,int inst, struct nas_priv *gpriv);
};
struct ipversion {
#if defined(__LITTLE_ENDIAN_BITFIELD)
uint8_t reserved:4,
version:4;
#else
uint8_t version:4,
reserved:4;
#endif
};
typedef struct pdcp_data_req_header_s {
rb_id_t rb_id;
sdu_size_t data_size;
signed int inst;
ip_traffic_type_t traffic_type;
uint32_t sourceL2Id;
uint32_t destinationL2Id;
} pdcp_data_req_header_t;
typedef struct pdcp_data_ind_header_s {
rb_id_t rb_id;
sdu_size_t data_size;
signed int inst;
ip_traffic_type_t dummy_traffic_type;
uint32_t sourceL2Id;
uint32_t destinationL2Id;
} pdcp_data_ind_header_t;
extern struct net_device *nasdev[NB_INSTANCES_MAX];
extern uint8_t NAS_NULL_IMEI[14];
#endif

View File

@@ -1,980 +0,0 @@
/*
* 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
*/
/***************************************************************************
nas_mesh.c - description
-------------------
copyright : (C) 2003-2008 by Eurecom
email : navid.nikaein@eurecom.fr
lionel.gauthier@eurecom.fr
raymond.knopp@eurecom.fr
***************************************************************************/
#include <linux/version.h>
#include "local.h"
#include "proto_extern.h"
//---------------------------------------------------------------------------
void nas_mesh_init(int inst)
{
//---------------------------------------------------------------------------
// struct cx_entity *cx;
printk("NAS_MESH_INIT Complete\n");
// Request the establishment of a connexion
// cx=nas_COMMON_search_cx(0);
// if (cx==NULL)
// {
// printk("NAS_MESH_INIT: connexion failure\n");
// return;
// }
// cx->countimer=5;
// cx->state=NAS_CX_CONNECTING;
// cx->retry=0;
// cx->cellid=25;
}
//---------------------------------------------------------------------------
//For demo, add automatically a classifier
//Equivalent to class add send 0 -f qos <x> -cr 0
void nas_mesh_start_broadcast_sclassifier(struct cx_entity *cx,struct rb_entity *rb)
{
struct classifier_entity *gc;
// Start debug information
#ifdef NAS_DEBUG_CLASS
printk("NAS_MESH_START_BROADCAST_SCLASS - begin \n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_MESH_START_DEFAULT_SCLASS - input parameter cx is NULL \n");
#endif
return;
}
if (rb==NULL) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_MESH_START_DEFAULT_SCLASS - input parameter rb is NULL \n");
#endif
return;
}
// End debug information
gc=nas_CLASS_add_sclassifier(cx, NAS_DSCP_DEFAULT, 6);
// gc=nas_CLASS_add_sclassifier(cx, 5, 0);
if (gc==NULL) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_MESH_START_DEFAULT_SCLASS - Classifier not added \n");
#endif
return;
}
gc->fct = nas_COMMON_QOS_send;
gc->rab_id =rb->rab_id; //5
gc->rb= rb;
gc->version = NAS_VERSION_DEFAULT;
gc->protocol= NAS_PROTOCOL_ICMP6;
// gc->sport = NAS_PORT_DEFAULT;
// gc->dport = NAS_PORT_DEFAULT;
#ifdef NAS_DEBUG_CLASS
printk("NAS_MESH_START_DEFAULT_SCLASS - end \n");
nas_print_classifier(gc);
#endif
}
void nas_mesh_start_default_sclassifier(struct cx_entity *cx,struct rb_entity *rb)
{
//---------------------------------------------------------------------------
#ifdef DEMO_3GSM
struct classifier_entity *gc;
// Start debug information
#ifdef NAS_DEBUG_CLASS
printk("NAS_MESH_START_DEFAULT_SCLASS - begin \n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_MESH_START_DEFAULT_SCLASS - input parameter cx is NULL \n");
#endif
return;
}
if (rb==NULL) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_MESH_START_DEFAULT_SCLASS - input parameter rb is NULL \n");
#endif
return;
}
// End debug information
gc=nas_CLASS_add_sclassifier(cx, NAS_DSCP_DEFAULT, 5);
// gc=nas_CLASS_add_sclassifier(cx, 5, 0);
if (gc==NULL) {
#ifdef NAS_DEBUG_CLASS
printk("NAS_MESH_START_DEFAULT_SCLASS - Classifier not added \n");
#endif
return;
}
gc->fct = nas_COMMON_QOS_send;
gc->rab_id =rb->rab_id; //5
gc->rb= rb;
gc->version = NAS_VERSION_DEFAULT;
gc->protocol= NAS_PROTOCOL_DEFAULT;
// gc->sport = NAS_PORT_DEFAULT;
// gc->dport = NAS_PORT_DEFAULT;
#ifdef NAS_DEBUG_CLASS
printk("NAS_MESH_START_DEFAULT_SCLASS - end \n");
nas_print_classifier(gc);
#endif
#endif
}
//---------------------------------------------------------------------------
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
void nas_mesh_timer(struct timer_list *t)
#else
void nas_mesh_timer(unsigned long data)
#endif
{
//---------------------------------------------------------------------------
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
struct nas_priv *gpriv=from_timer(gpriv, t, timer);
#else
struct nas_priv *gpriv=(struct nas_priv *) data;
#endif
uint8_t cxi;
struct cx_entity *cx;
struct rb_entity *rb;
// spin_lock(&gpriv->lock);
#ifdef NAS_DEBUG_TIMER
printk("NAS_MESH_TIMER - begin \n");
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
timer_setup(&gpriv->timer, nas_mesh_timer, 0);
mod_timer(&gpriv->timer, jiffies+NAS_TIMER_TICK);
#else
(gpriv->timer).function=nas_mesh_timer;
(gpriv->timer).expires=jiffies+NAS_TIMER_TICK;
(gpriv->timer).data=data;
#endif
return;
for (cxi=0; cxi<NAS_CX_MAX; ++cxi) {
cx=gpriv->cx+cxi;
if (cx==NULL) {
#ifdef NAS_DEBUG_TIMER
printk("NAS_MESH_TIMER - No pointer for connection %d \n", cxi);
#endif
continue;
}
if (cx->countimer!=NAS_TIMER_IDLE) {
#ifdef NAS_DEBUG_TIMER
printk("NAS_MESH_TIMER: lcr %u, countimer %u\n", cx->lcr, cx->countimer);
#endif
if (cx->countimer==0) {
switch (cx->state) {
case NAS_CX_CONNECTING:
case NAS_CX_CONNECTING_FAILURE:
if (cx->retry<gpriv->retry_limit)
nas_mesh_DC_send_cx_establish_request(cx,gpriv);
else {
printk("NAS_MESH_TIMER: Establishment failure\n");
cx->state=NAS_IDLE;
cx->retry=0;
cx->countimer=NAS_TIMER_IDLE;
}
break;
case NAS_CX_RELEASING_FAILURE:
nas_mesh_DC_send_cx_release_request(cx,gpriv);
break;
default:
printk("NAS_MESH_TIMER: default value\n");
cx->countimer=NAS_TIMER_IDLE;
}
} else
--cx->countimer;
}
for (rb=cx->rb; rb!=NULL; rb=rb->next) {
if (rb->countimer!=NAS_TIMER_IDLE) {
#ifdef NAS_DEBUG_TIMER
printk("NAS_MESH_TIMER : rb countimer %d, rb state %d\n", rb->countimer, rb->state);
#endif
if (rb->countimer==0) {
switch (rb->state) {
case NAS_RB_DCH:
nas_mesh_start_default_sclassifier(cx, rb);
rb->countimer=NAS_TIMER_IDLE;
break;
default:
rb->countimer=NAS_TIMER_IDLE;
}
} else {
--rb->countimer;
printk("NAS_MESH_TIMER : rb countimer-- %d, rb state %d\n", rb->countimer, rb->state);
}
}
}
}
// add_timer(&gpriv->timer);
// spin_unlock(&gpriv->lock);
}
//---------------------------------------------------------------------------
// Request the establishment of a connexion (DC channel)
int nas_mesh_DC_send_cx_establish_request(struct cx_entity *cx,struct nas_priv *gpriv)
{
//---------------------------------------------------------------------------
struct nas_ue_dc_element *p;
int bytes_wrote=0;
// Start debug information
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_SEND_CX_ESTABLISH - begin \n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_SEND_CX_ESTABLISH - input parameter cx is NULL \n");
#endif
return NAS_ERROR_NOTCORRECTVALUE;
}
// End debug information
switch (cx->state) {
case NAS_CX_CONNECTING:
case NAS_CX_CONNECTING_FAILURE:
case NAS_IDLE:
p= (struct nas_ue_dc_element *)(gpriv->xbuffer);
p->type = CONN_ESTABLISH_REQ;
p->length = NAS_TL_SIZE + sizeof(struct NASConnEstablishReq);
p->nasUEDCPrimitive.conn_establish_req.localConnectionRef = cx->lcr;
p->nasUEDCPrimitive.conn_establish_req.cellId = cx->cellid;
#ifdef NAS_DEBUG_DC
printk ("\nCONN_ESTABLISH_REQ Buffer to Xmit: ");
nas_tool_print_buffer((char *)p,p->length);
#endif
++cx->retry;
cx->countimer=gpriv->timer_establishment;
if (bytes_wrote==p->length) {
cx->state=NAS_CX_CONNECTING;
#ifdef NAS_DEBUG_DC
printk("nas_mesh_DC_send_cx_establish_req: Message sent successfully in DC-FIFO\n");
printk(" Local Connection reference %u\n", p->nasUEDCPrimitive.conn_establish_req.localConnectionRef);
printk(" Cell Identification %u\n", p->nasUEDCPrimitive.conn_establish_req.cellId);
print_TOOL_state(cx->state);
#endif
} else {
cx->state=NAS_CX_CONNECTING_FAILURE;
printk("NAS_MESH_DC_SEND_CX_ESTABLISHMENT_REQUEST: Message sent failure in DC-FIFO\n");
print_TOOL_state(cx->state);
}
return bytes_wrote;
default:
return -NAS_ERROR_NOTIDLE;
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_SEND_CX_ESTABLISH - NAS_ERROR_NOTIDLE \n");
#endif
}
}
//---------------------------------------------------------------------------
// Request the release of a connexion (DC channel)
int nas_mesh_DC_send_cx_release_request(struct cx_entity *cx,
struct nas_priv *gpriv)
{
//---------------------------------------------------------------------------
struct nas_ue_dc_element *p;
int bytes_wrote=0;
// Start debug information
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_SEND_CX_RELEASE - begin \n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_SEND_CX_RELEASE - input parameter cx is NULL \n");
#endif
return NAS_ERROR_NOTCORRECTVALUE;
}
// End debug information
switch (cx->state) {
case NAS_CX_RELEASING_FAILURE:
case NAS_CX_DCH:
p= (struct nas_ue_dc_element *)(gpriv->xbuffer);
p->type = CONN_RELEASE_REQ;
p->length = NAS_TL_SIZE + sizeof(struct NASConnReleaseReq);
p->nasUEDCPrimitive.conn_release_req.localConnectionRef = cx->lcr;
p->nasUEDCPrimitive.conn_release_req.releaseCause = NAS_CX_RELEASE_UNDEF_CAUSE;
if (bytes_wrote==p->length) {
cx->state=NAS_IDLE;
cx->iid4=0;
// nas_TOOL_imei2iid(NAS_NULL_IMEI, (uint8_t *)cx->iid6);
nas_COMMON_flush_rb(cx);
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_SEND_CX_RELEASE_REQUEST: Message sent successfully in DC-FIFO\n");
printk(" Local Connection Reference %u\n", p->nasUEDCPrimitive.conn_release_req.localConnectionRef);
printk(" Release Cause %u\n", p->nasUEDCPrimitive.conn_release_req.releaseCause);
print_TOOL_state(cx->state);
#endif
} else {
++cx->retry;
cx->countimer=gpriv->timer_release;
cx->state=NAS_CX_RELEASING_FAILURE;
printk("NAS_MESH_DC_SEND_CX_RELEASE_REQUEST: Message sent failure in DC-FIFO\n");
print_TOOL_state(cx->state);
}
return bytes_wrote;
default:
return -NAS_ERROR_NOTCONNECTED;
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_SEND_CX_RELEASE_REQUEST - NAS_ERROR_NOTCONNECTED \n");
#endif
}
}
//---------------------------------------------------------------------------
// Request the transfer of data (DC SAP)
void nas_mesh_DC_send_sig_data_request(struct sk_buff *skb,
struct cx_entity *cx,
struct classifier_entity *gc,
int inst,
struct nas_priv *gpriv)
{
//---------------------------------------------------------------------------
struct nas_ue_dc_element *p;
//char data_type = 'A';
int bytes_wrote=0;
// Start debug information
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_SEND_SIG - begin \n");
#endif
if (skb==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_SEND_SIG - input parameter skb is NULL \n");
#endif
return;
}
if (gc==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_SEND_SIG - input parameter gc is NULL \n");
#endif
return;
}
if (cx==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_SEND_SIG - input parameter cx is NULL \n");
#endif
return;
}
// End debug information
if (cx->state!=NAS_CX_DCH) {
printk("NAS_MESH_DC_SEND_SIG: Not connected, so the message is dropped\n");
++gpriv->stats.tx_dropped;
return;
}
p = (struct nas_ue_dc_element *)(gpriv->xbuffer);
p->type = DATA_TRANSFER_REQ;
p->length = NAS_TL_SIZE + sizeof(struct NASDataReq);
p->nasUEDCPrimitive.data_transfer_req.localConnectionRef = cx->lcr;
p->nasUEDCPrimitive.data_transfer_req.priority = 3; // TBD
p->nasUEDCPrimitive.data_transfer_req.nasDataLength = (skb->len)+1; //adds category character
if (bytes_wrote!=p->length) {
printk("NAS_MESH_DC_SEND_SIG: Header sent failure in DC-FIFO\n");
return;
}
if (bytes_wrote != p->length + skb->len + 1) {
printk("NAS_MESH_DC_SEND_SIG: Data sent failure in DC-FIFO\n");
return;
}
gpriv->stats.tx_bytes += skb->len;
gpriv->stats.tx_packets ++;
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_SEND_SIG - end \n");
#endif
}
//---------------------------------------------------------------------------
// Request the transfer of data (DC SAP)
void nas_mesh_DC_send_peer_sig_data_request(struct cx_entity *cx, uint8_t sig_category,
struct nas_priv *gpriv)
{
//---------------------------------------------------------------------------
struct nas_ue_dc_element *p;
uint8_t nas_data[10];
unsigned int nas_length;
//char data_type = 'Z';
int bytes_wrote=0;
// Start debug information
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_PEER_SEND_SIG - begin \n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_PEER_SEND_SIG - input parameter cx is NULL \n");
#endif
return;
}
// End debug information
if (cx->state!=NAS_CX_DCH) {
printk("NAS_MESH_DC_PEER_SEND_SIG: Not connected, so the message is dropped\n");
return;
}
// Initialize peer message
nas_length = 10;
memset (nas_data, 0, nas_length);
nas_data[0]= sig_category;
//
p = (struct nas_ue_dc_element *)(gpriv->xbuffer);
p->type = DATA_TRANSFER_REQ;
p->length = NAS_TL_SIZE + sizeof(struct NASDataReq);
p->nasUEDCPrimitive.data_transfer_req.localConnectionRef = cx->lcr;
p->nasUEDCPrimitive.data_transfer_req.priority = 3; // TBD
p->nasUEDCPrimitive.data_transfer_req.nasDataLength = (nas_length)+1; //adds category character
if (bytes_wrote!=p->length) {
printk("NAS_MESH_DC_PEER_SEND_SIG: Header sent failure in DC-FIFO\n");
return;
}
if (bytes_wrote != p->length + nas_length + 1) {
printk("NAS_MESH_DC_PEER_SEND_SIG: Data sent failure in DC-FIFO\n");
return;
}
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_PEER_SEND_SIG - end \n");
#endif
}
//---------------------------------------------------------------------------
// Decode CONN_ESTABLISH_RESP message from RRC
void nas_mesh_DC_decode_cx_establish_resp(struct cx_entity *cx, struct nas_ue_dc_element *p,struct nas_priv *gpriv)
{
//---------------------------------------------------------------------------
uint8_t sig_category;
// Start debug information
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_CX_ESTABLISH - begin \n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_CX_ESTABLISH - input parameter cx is NULL \n");
#endif
return;
}
if (p==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_CX_ESTABLISH - input parameter p is NULL \n");
#endif
return;
}
// End debug information
cx->retry=0;
if (p->nasUEDCPrimitive.conn_establish_resp.status == TERMINATED) {
cx->state=NAS_CX_DCH; //to be changed to NAS_CX_FACH
cx->iid4=1;
//nas_TOOL_imei2iid(NAS_RG_IMEI, (uint8_t *)cx->iid6);
sig_category = NAS_CMD_OPEN_RB;
//For demo, add automatically a radio bearer
#ifdef DEMO_3GSM
printk("NAS_MESH_DC_DECODE_CX_ESTABLISH - sig_category %u \n", sig_category);
nas_mesh_DC_send_peer_sig_data_request(cx, sig_category,gpriv);
#endif
} else {
cx->state=NAS_IDLE;
}
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_RECEIVE: CONN_ESTABLISH_RESP\n");
printk("Local Connection reference %u\n",p->nasUEDCPrimitive.conn_establish_resp.localConnectionRef);
printk("Connection Establishment status %u\n",p->nasUEDCPrimitive.conn_establish_resp.status);
print_TOOL_state(cx->state);
#endif
}
//---------------------------------------------------------------------------
// Decode CONN_LOSS_IND message from RRC
void nas_mesh_DC_decode_cx_loss_ind(struct cx_entity *cx, struct nas_ue_dc_element *p)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_CX_LOSS - begin \n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_CX_LOSS - input parameter cx is NULL \n");
#endif
return;
}
if (p==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_CX_LOSS - input parameter p is NULL \n");
#endif
return;
}
// End debug information
cx->state=NAS_IDLE;
cx->iid4=0;
//nas_TOOL_imei2iid(NAS_NULL_IMEI, (uint8_t *)cx->iid6);
nas_COMMON_flush_rb(cx);
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_RECEIVE: CONN_LOSS_IND reception\n");
printk(" Local Connection reference %u\n", p->nasUEDCPrimitive.conn_loss_ind.localConnectionRef);
print_TOOL_state(cx->state);
#endif
}
//---------------------------------------------------------------------------
// Decode CONN_RELEASE_IND message from RRC
//void nas_mesh_DC_decode_cx_release_ind(struct cx_entity *cx, struct nas_ue_dc_element *p){
//---------------------------------------------------------------------------
// printk("\t\tCONN_RELEASE_IND\n");
// printk("\t\tLocal Connection reference %u\n", p->nasUEDCPrimitive.conn_release_ind.localConnectionRef);
// printk("\t\tRelease cause %u\n", p->nasRGDCPrimitive.conn_release_ind.releaseCause);
// if (gpriv->cx[cxi].state==NAS_CX_DCH)
// {
// gpriv->cx[cxi].state=NAS_IDLE;
// printk("\t\tMobile no more connected\n");
// return bytes_read;
// }
// printk("\t\tIncoherent state %u\n", gpriv->cx[cxi].state);
// return bytes_read;
//}
//---------------------------------------------------------------------------
// Decode DATA_TRANSFER_IND message from RRC
void nas_mesh_DC_decode_sig_data_ind(struct cx_entity *cx, struct nas_ue_dc_element *p)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_SIG_DATA_IND - begin \n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_SIG_DATA_IND - input parameter cx is NULL \n");
#endif
return;
}
if (p==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_SIG_DATA_IND - input parameter p is NULL \n");
#endif
return;
}
// End debug information
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_RECEIVE: DATA_TRANSFER_IND reception\n");
printk(" Local Connection reference %u\n",p->nasUEDCPrimitive.data_transfer_ind.localConnectionRef);
printk(" Signaling Priority %u\n",p->nasUEDCPrimitive.data_transfer_ind.priority);
printk(" NAS Data length %u\n",p->nasUEDCPrimitive.data_transfer_ind.nasDataLength);
printk(" NAS Data string %s\n", (uint8_t *)p+p->length);
#endif
}
//---------------------------------------------------------------------------
// Decode RB_ESTABLISH_IND message from RRC
void nas_mesh_DC_decode_rb_establish_ind(struct cx_entity *cx, struct nas_ue_dc_element *p,struct nas_priv *gpriv)
{
//---------------------------------------------------------------------------
struct rb_entity *rb;
// Start debug information
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_RB_ESTABLISH_IND - begin \n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_RB_ESTABLISH_IND - input parameter cx is NULL \n");
#endif
return;
}
if (p==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_RB_ESTABLISH_IND - input parameter p is NULL \n");
#endif
return;
}
// End debug information
rb=nas_COMMON_search_rb(cx, p->nasUEDCPrimitive.rb_release_ind.rbId);
if (rb==NULL) {
rb=nas_COMMON_add_rb(cx, p->nasUEDCPrimitive.rb_establish_ind.rbId, p->nasUEDCPrimitive.rb_establish_ind.QoSclass);
rb->state=NAS_RB_DCH;
cx->state=NAS_CX_DCH;
//For demo, add automatically a classifier
#ifdef DEMO_3GSM
rb->countimer=gpriv->timer_establishment+10;
#endif
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_RB_ESTABLISH_IND: RB_ESTABLISH_IND reception\n");
printk(" Local Connection reference %u\n",p->nasUEDCPrimitive.rb_establish_ind.localConnectionRef);
printk(" Radio Bearer Identity %u \n",p->nasUEDCPrimitive.rb_establish_ind.rbId);
printk(" QoS Traffic Class %u\n",p->nasUEDCPrimitive.rb_establish_ind.QoSclass);
printk(" DSCP Code %u\n",p->nasUEDCPrimitive.rb_establish_ind.dscp);
printk(" SAP Id %u\n",p->nasUEDCPrimitive.rb_establish_ind.sapId);
print_TOOL_state(cx->state);
nas_print_rb_entity(rb);
#endif
} else
printk("NAS_MESH_DC_DECODE_RB_ESTABLISH_IND: RB_ESTABLISH_IND reception, Radio bearer already opened\n");
}
//---------------------------------------------------------------------------
// Decode RB_RELEASE_IND message from RRC
void nas_mesh_DC_decode_rb_release_ind(struct cx_entity *cx, struct nas_ue_dc_element *p)
{
//---------------------------------------------------------------------------
struct rb_entity *rb;
// Start debug information
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_RB_RELEASE_IND - begin \n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_RB_RELEASE_IND - input parameter cx is NULL \n");
#endif
return;
}
if (p==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_RB_RELEASE_IND - input parameter p is NULL \n");
#endif
return;
}
// End debug information
rb=nas_COMMON_search_rb(cx, p->nasUEDCPrimitive.rb_release_ind.rbId);
if (rb!=NULL) {
rb->state=NAS_IDLE;
//needs also to flush corresponding control block to be coherent with add_rb
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_RB_RELEASE_IND: RB_RELEASE_IND reception\n");
printk("Local Connection reference %u\n",p->nasUEDCPrimitive.rb_release_ind.localConnectionRef);
printk("Radio Bearer Identity %u\n",p->nasUEDCPrimitive.rb_release_ind.rbId);
print_TOOL_state(cx->state);
#endif
} else
printk("NAS_DC_RG_RECEIVE: RB_RELEASE_IND reception, No corresponding radio bearer\n");
}
//---------------------------------------------------------------------------
// Decode MEASUREMENT_IND message from RRC
void nas_mesh_DC_decode_measurement_ind(struct cx_entity *cx, struct nas_ue_dc_element *p)
{
//---------------------------------------------------------------------------
uint8_t i;
// Start debug information
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_MEASUREMENT_IND - begin \n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_MEASUREMENT_IND - input parameter cx is NULL \n");
#endif
return;
}
if (p==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_DECODE_MEASUREMENT_IND - input parameter p is NULL \n");
#endif
return;
}
// End debug information
#ifdef NAS_DEBUG_DC_MEASURE
printk("NAS_MESH_DC_RECEIVE: MEASUREMENT_IND reception\n");
printk(" Local Connection reference: %u\n", p->nasUEDCPrimitive.measurement_ind.localConnectionRef);
printk(" Number of RGs: %u\n", p->nasUEDCPrimitive.measurement_ind.nb_rg);
print_TOOL_state(cx->state);
for (i=0; i<p->nasUEDCPrimitive.measurement_ind.nb_rg; ++i) {
printk(" RG[%u]: Cell_Id %u, Level: %u\n", i,
p->nasUEDCPrimitive.measurement_ind.measures[i].cell_id,
p->nasUEDCPrimitive.measurement_ind.measures[i].level);
}
#endif //NAS_DEBUG_DC_MEASURE
cx->num_measures = p->nasUEDCPrimitive.measurement_ind.nb_rg;
for (i=0; i<cx->num_measures; i++) {
cx->meas_cell_id[i]= (int)(p->nasUEDCPrimitive.measurement_ind.measures[i].cell_id);
cx->meas_level[i] = (int)(p->nasUEDCPrimitive.measurement_ind.measures[i].level);
//npriv->provider_id[i]=;
}
cx->provider_id[0]=25;
cx->provider_id[1]=1;
cx->provider_id[2]=25;
}
//---------------------------------------------------------------------------
// Check if anything in DC FIFO and decode it (MESH)
int nas_mesh_DC_receive(struct cx_entity *cx,struct nas_priv *gpriv)
{
//---------------------------------------------------------------------------
// Start debug information
int bytes_read=0;
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_RECEIVE - begin \n");
#endif
if (cx==NULL) {
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_RECEIVE - input parameter cx is NULL \n");
#endif
return NAS_ERROR_NOTCORRECTVALUE;
}
// End debug information
if (bytes_read>0) {
struct nas_ue_dc_element *p;
p= (struct nas_ue_dc_element *)(gpriv->rbuffer);
//get the rest of the primitive
if (bytes_read!=p->length) {
printk("NAS_MESH_DC_RECEIVE: Problem while reading primitive header\n");
return bytes_read;
}
switch (p->type) {
case CONN_ESTABLISH_RESP :
if (p->nasUEDCPrimitive.conn_establish_resp.localConnectionRef!=cx->lcr)
printk("NAS_MESH_DC_RECEIVE: CONN_ESTABLISH_RESP, Local connection reference not correct %u\n",p->nasUEDCPrimitive.conn_establish_resp.localConnectionRef);
else {
switch (cx->state) {
case NAS_CX_CONNECTING:
nas_mesh_DC_decode_cx_establish_resp(cx,p,gpriv); // process message
break;
default:
printk("NAS_MESH_DC_RECEIVE: CONN_ESTABLISH_RESP reception, Invalid state %u\n", cx->state);
}
}
break;
case CONN_LOSS_IND :
if (p->nasUEDCPrimitive.conn_loss_ind.localConnectionRef!=cx->lcr)
printk("NAS_MESH_DC_RECEIVE: CONN_LOSS_IND reception, Local connection reference not correct %u\n", p->nasUEDCPrimitive.conn_loss_ind.localConnectionRef);
else {
switch (cx->state) {
case NAS_CX_RELEASING_FAILURE:
cx->retry=0;
/* fallthrough */
case NAS_CX_DCH:
nas_mesh_DC_decode_cx_loss_ind(cx,p); // process message
break;
default:
printk("NAS_MESH_DC_RECEIVE: CONN_LOSS_IND reception, Invalid state %u", cx->state);
}
}
break;
// case CONN_RELEASE_IND :
// break;
case DATA_TRANSFER_IND :
if (p->nasUEDCPrimitive.data_transfer_ind.localConnectionRef!=cx->lcr)
printk("NAS_MESH_DC_RECEIVE: DATA_TRANSFER_IND reception, Local connection reference not correct %u\n", p->nasUEDCPrimitive.conn_loss_ind.localConnectionRef);
else {
switch (cx->state) {
case NAS_CX_FACH:
case NAS_CX_DCH:
nas_mesh_DC_decode_sig_data_ind(cx,p); // process message
break;
default:
printk("NAS_MESH_DC_RECEIVE: DATA_TRANSFER_IND reception, Invalid state %u", cx->state);
}
}
break;
case RB_ESTABLISH_IND :
if (p->nasUEDCPrimitive.rb_establish_ind.localConnectionRef!=cx->lcr)
printk("NAS_MESH_DC_RECEIVE: RB_ESTABLISH_IND reception, Local connexion reference not correct %u\n", p->nasUEDCPrimitive.rb_establish_ind.localConnectionRef);
else {
switch (cx->state) {
case NAS_CX_FACH:
case NAS_CX_DCH:
nas_mesh_DC_decode_rb_establish_ind(cx,p,gpriv); // process message
break;
default:
printk("NAS_MESH_DC_RECEIVE: RB_ESTABLISH_IND reception, Invalid state %u", cx->state);
}
}
break;
case RB_RELEASE_IND :
if (p->nasUEDCPrimitive.rb_release_ind.localConnectionRef!=cx->lcr)
printk("NAS_DC_MESH_RECEIVE: RB_RELEASE_IND reception, Local connection reference not correct %u\n", p->nasUEDCPrimitive.rb_release_ind.localConnectionRef);
else {
switch (cx->state) {
case NAS_CX_DCH:
nas_mesh_DC_decode_rb_release_ind(cx,p); // process message
break;
default:
printk("NAS_MESH_DC_RECEIVE: RB_RELEASE_IND reception, Invalid state %u", cx->state);
}
}
break;
case MEASUREMENT_IND :
if (p->nasUEDCPrimitive.measurement_ind.localConnectionRef!=cx->lcr)
printk("NAS_MESH_DC_RECEIVE: MEASUREMENT_IND reception, Local connection reference not correct %u\n", p->nasUEDCPrimitive.measurement_ind.localConnectionRef);
else {
nas_mesh_DC_decode_measurement_ind(cx,p);
}
break;
default :
printk("NAS_MESH_DC_RECEIVE: Invalid message received\n");
}
}
#ifdef NAS_DEBUG_DC
printk("NAS_MESH_DC_RECEIVE - end \n");
#endif
return bytes_read;
}
//---------------------------------------------------------------------------
// Check if anything in GC FIFO and decode it (MESH)
int nas_mesh_GC_receive(struct nas_priv *gpriv)
{
//---------------------------------------------------------------------------
int bytes_read=0;
#ifdef NAS_DEBUG_GC
printk("NAS_MESH_GC_RECEIVE - begin \n");
#endif
if (bytes_read>0) {
struct nas_ue_gc_element *p;
p= (struct nas_ue_gc_element *)(gpriv->rbuffer);
//get the rest of the primitive
if (bytes_read!=p->length) {
printk("NAS_MESH_GC_RECEIVE: Problem while reading primitive's header\n");
return bytes_read;
}
// start decoding message
switch (p->type) {
case INFO_BROADCAST_IND :
if (bytes_read!=p->length+p->nasUEGCPrimitive.broadcast_ind.nasDataLength) {
printk("NAS_MESH_GC_RECEIVE: INFO_BROADCAST_IND reception, Problem while reading primitive's data\n");
return bytes_read;
}
#ifdef NAS_DEBUG_GC
printk("NAS_MESH_GC_RECEIVE: INFO_BROADCAST_IND reception\n");
printk(" Primitive length %d \n", (int)(p->type));
printk(" Data length %u\n", p->nasUEGCPrimitive.broadcast_ind.nasDataLength);
printk(" Data string %s\n", (uint8_t *)p+p->length);
#endif //NAS_DEBUG_GC
return bytes_read;
default :
printk("NAS_MESH_GC_RECEIVE: Invalid message received\n");
return -1;
}
} else
return -1;
}

View File

@@ -1,212 +0,0 @@
/*
* 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
*/
/*! \file netlink.c
* \brief establish a netlink
* \author Navid Nikaein, Lionel Gauthier, and Raymond knopp
* \company Eurecom
* \email:navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr, knopp@eurecom.fr
*/
//#include <linux/config.h>
#include <linux/version.h>
#include <linux/socket.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netlink.h>
#include <net/sock.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
#include "local.h"
#include "proto_extern.h"
//#include "common/platform_constants.h"
//#define NETLINK_DEBUG 1
#define OAI_IP_DRIVER_NETLINK_ID 31
#define NL_DEST_PID 1
static struct sock *nas_nl_sk = NULL;
static int exit_netlink_thread=0;
//static int nas_netlink_rx_thread(void *);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
struct netlink_kernel_cfg oai_netlink_cfg;
#endif
static DEFINE_MUTEX(nasmesh_mutex);
static inline void nasmesh_lock(void)
{
mutex_lock(&nasmesh_mutex);
}
static inline void nasmesh_unlock(void)
{
mutex_unlock(&nasmesh_mutex);
}
// This can also be implemented using thread to get the data from PDCP without blocking.
static void nas_nl_data_ready (struct sk_buff *skb)
{
// wake_up_interruptible(skb->sk->sk_sleep);
//nasmesh_lock();
//netlink_rcv_skb(skb, &my_rcv_msg);// my_rcv_msg is the call back func>
//nasmesh_unlock();
struct nlmsghdr *nlh = NULL;
//int j;
if (skb) {
#ifdef NETLINK_DEBUG
printk("[NAS][NETLINK] Received socket from PDCP\n");
#endif //NETLINK_DEBUG
nlh = (struct nlmsghdr *)skb->data;
nas_COMMON_QOS_receive(nlh);
//kfree_skb(skb); // not required,
}
}
int nas_netlink_init()
{
printk("[NAS][NETLINK] Running init ...\n");
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
oai_netlink_cfg.groups = 0;
oai_netlink_cfg.input = nas_nl_data_ready;
oai_netlink_cfg.cb_mutex = &nasmesh_mutex;
oai_netlink_cfg.bind = NULL;
nas_nl_sk = netlink_kernel_create(
&init_net,
OAI_IP_DRIVER_NETLINK_ID,
# if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
THIS_MODULE,
# endif
&oai_netlink_cfg);
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */
nas_nl_sk = netlink_kernel_create(
&init_net,
OAI_IP_DRIVER_NETLINK_ID,
0,
nas_nl_data_ready,
&nasmesh_mutex, // NULL
THIS_MODULE);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */
if (nas_nl_sk == NULL) {
printk("[NAS][NETLINK] netlink_kernel_create failed \n");
return(-1);
}
return(0);
}
void nas_netlink_release(void)
{
exit_netlink_thread=1;
printk("[NAS][NETLINK] Releasing netlink socket\n");
if(nas_nl_sk) {
netlink_kernel_release(nas_nl_sk); //or skb->sk
}
// printk("[NAS][NETLINK] Removing netlink_rx_thread\n");
//kthread_stop(netlink_rx_thread);
}
int nas_netlink_send(unsigned char *data,unsigned int len)
{
struct sk_buff *nl_skb = alloc_skb(NLMSG_SPACE(len),GFP_ATOMIC);
struct nlmsghdr *nlh = (struct nlmsghdr *)nl_skb->data;
int status;
//printk("[NAS][NETLINK] Sending %d bytes (%d)\n",len,NLMSG_SPACE(len));
skb_put(nl_skb, NLMSG_SPACE(len));
memcpy(NLMSG_DATA(nlh),data,len);
nlh->nlmsg_len = NLMSG_SPACE(len);
nlh->nlmsg_pid = 0; /* from kernel */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
NETLINK_CB(nl_skb).portid = 0;
#else
NETLINK_CB(nl_skb).pid = 0;
#endif
#ifdef NETLINK_DEBUG
printk("[NAS][NETLINK] In nas_netlink_send, nl_skb %p, nl_sk %x, nlh %p, nlh->nlmsg_len %d (OAI_IP_DRIVER_NETLINK_ID %d)\n",
nl_skb,nas_nl_sk,nlh,nlh->nlmsg_len,
OAI_IP_DRIVER_NETLINK_ID);
#endif //DEBUG_NETLINK
if (nas_nl_sk) {
// nasmesh_lock();
status = netlink_unicast(nas_nl_sk, nl_skb, NL_DEST_PID, MSG_DONTWAIT);
// mutex_unlock(&nasmesh_mutex);
if (status < 0) {
printk("[NAS][NETLINK] SEND status is %d\n",status);
return(0);
} else {
#ifdef NETLINK_DEBUG
printk("[NAS][NETLINK] SEND status is %d\n",status);
#endif
return len;
}
} else {
printk("[NAS][SEND] socket is NULL\n");
return(0);
}
/*
nlmsg_failure: // Used by NLMSG_PUT
if (nl_skb)
kfree_skb(nl_skb);
*/
}

View File

@@ -1,304 +0,0 @@
/*
* 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
*/
/***************************************************************************
nas_proto_extern.h - description
-------------------
copyright : (C) 2002 by Eurecom
email : navid.nikaein@eurecom.fr
lionel.gauthier@eurecom.fr
knopp@eurecom.fr
***************************************************************************/
#ifndef __NETWORK_DRIVER_MESH_PROTO_EXTERN__H__
#define __NETWORK_DRIVER_MESH_PROTO_EXTERN__H__
#include <linux/if_arp.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/ipv6.h>
#include <linux/ip.h>
#include <linux/sysctl.h>
#include <linux/timer.h>
#include <asm/param.h>
//#include <sys/sysctl.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
#include <linux/in.h>
#include <net/ndisc.h>
//#include "rrc_nas_primitives.h"
//#include "protocol_vars_extern.h"
//#include "as_sap.h"
//#include "rrc_qos.h"
//#include "rrc_sap.h"
#include "local.h"
// device.c
/** @defgroup _nas_mesh_impl_ NAS Mesh Network Device
* @ingroup _ref_implementation_
* @{
\fn int find_inst(struct net_device *dev)
\brief This function determines the instance id for a particular device pointer.
@param dev Pointer to net_device structure
*/
int find_inst(struct net_device *dev);
// nas_common.c
/**
\fn void nas_COMMON_receive(unsigned short dlen, void* pdcp_sdu,int inst,struct classifier_entity *rclass,nasRadioBearerId_t rb_id)
\brief Receive data from FIFO (QOS)
@param dlen Length of SDU in bytes
@param pdcp_sdu Pointer to received SDU
@param inst Instance number
@param rclass RX Classifier entity
@param rb_id Radio Bearer Id
*/
void nas_COMMON_receive(unsigned short dlen,
void *pdcp_sdu,
int inst,
struct classifier_entity *rclass,
nasRadioBearerId_t rb_id);
/**
\fn void nas_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,int inst)
\brief Request the transfer of data (QoS SAP)
@param skb pointer to socket buffer
@param cx pointer to connection entity for SDU
@param gc pointer to classifier entity for SDU
@param inst device instance
*/
void nas_COMMON_QOS_send(struct sk_buff *skb,
struct cx_entity *cx,
struct classifier_entity *gc,int inst, struct nas_priv *gpriv);
/**
\fn void nas_COMMON_del_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,int inst)
\brief Delete the data
@param skb pointer to socket buffer
@param cx pointer to connection entity for SDU
@param gc pointer to classifier entity for SDU
@param inst device instance
*/
void nas_COMMON_del_send(struct sk_buff *skb,
struct cx_entity *cx,
struct classifier_entity *gc,int inst, struct nas_priv *gpriv);
/**
\fn struct rb_entity *nas_COMMON_add_rb(struct cx_entity *cx, nasRadioBearerId_t rabi, nasQoSTrafficClass_t qos)
\brief Add a radio-bearer descriptor
@param cx pointer to connection entity
@param rabi radio-bearer index
@param qos NAS QOS traffic class
*/
struct rb_entity *nas_COMMON_add_rb(
struct cx_entity *cx, nasRadioBearerId_t rabi,
nasQoSTrafficClass_t qos);
/**
\fn struct rb_entity *nas_COMMON_search_rb(struct cx_entity *cx, nasRadioBearerId_t rabi)
\brief Search for a radio-bearer entity for a particular connection and radio-bearer index
@param cx pointer to connection entity
@param rabi radio-bearer index
@returns A pointer to the radio-bearer entity
*/
struct rb_entity *nas_COMMON_search_rb(
struct cx_entity *cx, nasRadioBearerId_t rabi);
/**
\fn struct cx_entity *nas_COMMON_search_cx(nasLocalConnectionRef_t lcr,struct nas_priv *gpriv)
\brief Search for a connection entity based on its index and pointer to nas_priv
@param lcr index of local connection
@param gpriv pointer to nas_priv for device
@returns A pointer to the connection entity
*/
struct cx_entity *nas_COMMON_search_cx(
nasLocalConnectionRef_t lcr,
struct nas_priv *gpriv);
/**
\fn struct classifier_entity *nas_COMMON_search_class_for_rb(nasRadioBearerId_t rab_id,struct nas_priv *priv)
\brief Search for an RX classifier entity based on a RB id and pointer to nas_priv
@param rab_id Index of RAB for search
@param priv pointer to nas_priv for device
@returns A pointer to the corresponding RX classifier entity
*/
struct classifier_entity
*nas_COMMON_search_class_for_rb(nasRadioBearerId_t
rab_id,struct nas_priv *priv);
/**
\fn void nas_COMMON_flush_rb(struct cx_entity *cx)
\brief Clear all RB's for a particular connection
@param cx pointer to connection entity
*/
void nas_COMMON_flush_rb(struct cx_entity *cx);
/**
\fn int nas_netlink_send(unsigned char *data,unsigned int len)
\brief Request the transfer of data by PDCP via netlink socket
@param data pointer to SDU
@param len length of SDU in bytes
@returns Numeber of bytes transfered by netlink socket
*/
int nas_netlink_send(unsigned char *data,unsigned int len);
/**
\fn void nas_COMMON_QOS_receive(struct nlmsghdr *nlh)
\brief Request a PDU from PDCP
@param nlh pointer to netlink message header
*/
void nas_COMMON_QOS_receive(struct nlmsghdr *nlh);
//nasmesh.c
/**
\brief Initialize an interface for a particular instance ID.
*/
void nas_mesh_init(int inst //!< Instance ID
);
int nas_mesh_DC_receive(struct cx_entity *cx,struct nas_priv *gpriv);
int nas_mesh_GC_receive(struct nas_priv *gpriv);
int nas_mesh_DC_send_cx_establish_request(struct cx_entity *cx,struct nas_priv *gpriv);
int nas_mesh_DC_send_cx_release_request(struct cx_entity *cx,struct nas_priv *gpriv);
void nas_mesh_DC_send_sig_data_request(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,int inst, struct nas_priv *gpriv);
// iocontrol.c
void nas_CTL_send(struct sk_buff *skb,
struct cx_entity *cx,
struct classifier_entity *gc,int inst, struct nas_priv *gpriv);
//int nas_CTL_receive_authentication(struct ipv6hdr *iph, struct cx-entity *cx, unsigned char sapi);
int nas_CTL_ioctl(struct net_device *dev,
struct ifreq *ifr, int cmd);
// classifier.c
/**
\brief Send a socket received from IP to classifier for a particular instance ID.
*/
void nas_CLASS_send(struct sk_buff *skb, //!< Pointer to socket buffer
int inst //!< Instance ID
);
/**
\brief
*/
struct classifier_entity *nas_CLASS_add_sclassifier(struct cx_entity *cx, unsigned char dscp, unsigned short classref);
/**
\brief Send a socket received from IP to classifier for a particular instance ID.
*/
struct classifier_entity
*nas_CLASS_add_fclassifier(struct cx_entity *cx,
unsigned char dscp,
unsigned short classref
);
/**
\brief Send a socket received from IP to classifier for a particular instance ID.
*/
struct classifier_entity
*nas_CLASS_add_rclassifier(unsigned char dscp,
unsigned short classref,
struct nas_priv*
);
/**
\brief
*/
void nas_CLASS_del_sclassifier(struct cx_entity *cx,
unsigned char dscp,
unsigned short classref
);
/**
\brief
*/
void nas_CLASS_del_fclassifier(struct cx_entity *cx,
unsigned char dscp,
unsigned short classref
);
/**
\brief
*/
void nas_CLASS_del_rclassifier(unsigned char dscp,
unsigned short classref,
struct nas_priv*
);
/**
\brief
*/
void nas_CLASS_flush_sclassifier(struct cx_entity *cx
);
/**
\brief
*/
void nas_CLASS_flush_fclassifier(struct cx_entity *cx
);
/**
\brief
*/
void nas_CLASS_flush_rclassifier(struct nas_priv *gpriv
);
// nas_tool.c
unsigned char nas_TOOL_invfct(struct classifier_entity *gc);
void nas_TOOL_fct(struct classifier_entity *gc, unsigned char fct);
void nas_TOOL_imei2iid(unsigned char *imei, unsigned char *iid);
unsigned char nas_TOOL_get_dscp6(struct ipv6hdr *iph);
unsigned char nas_TOOL_get_dscp4(struct iphdr *iph);
unsigned char *nas_TOOL_get_protocol6(struct ipv6hdr *iph, unsigned char *protocol);
unsigned char *nas_TOOL_get_protocol4(struct iphdr *iph, unsigned char *protocol);
char *nas_TOOL_get_udpmsg(struct udphdr *udph);
unsigned short nas_TOOL_udpcksum(struct in6_addr *saddr, struct in6_addr *daddr, unsigned char proto, unsigned int udplen, void *data);
int nas_TOOL_network6(struct in6_addr *addr, struct in6_addr *prefix, unsigned char plen);
int nas_TOOL_network4(unsigned int *addr, unsigned int *prefix, unsigned char plen);
void print_TOOL_pk_icmp6(struct icmp6hdr *icmph);
void print_TOOL_pk_all(struct sk_buff *skb);
void print_TOOL_pk_ipv6(struct ipv6hdr *iph);
void print_TOOL_state(unsigned char state);
void nas_tool_print_buffer(char * buffer,int length);
void nas_print_rb_entity(struct rb_entity *rb);
void nas_print_classifier(struct classifier_entity *gc);
// nas_netlink.c
void nas_netlink_release(void);
int nas_netlink_init(void);
/** @} */
#endif

View File

@@ -1,280 +0,0 @@
/*
* 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
*/
/*********************************************************************
rrc_nas_primitives.h - description
-------------------
begin : Jan 11, 2002
copyright : (C) 2001 by Eurecom
email : navid.nikaein@eurecom.fr
lionel.gauthier@eurecom.fr
knopp@eurecom.fr
*********************************************************************
Define RRC external interface primitives
********************************************************************/
#ifndef __RRC_NASPRIM_H__
# define __RRC_NASPRIM_H__
//----------------------------------------------------------
// Primitives
//----------------------------------------------------------
# define INFO_BROADCAST_REQ 1
# define INFO_BROADCAST_IND 2
# define CONN_ESTABLISH_REQ 3
# define CONN_ESTABLISH_IND 4
# define CONN_ESTABLISH_RESP 5
# define CONN_ESTABLISH_CNF 6
# define CONN_RELEASE_REQ 7
# define CONN_RELEASE_IND 8
# define DATA_TRANSFER_REQ 9
# define DATA_TRANSFER_IND 10
# define RB_ESTABLISH_REQ 11
# define RB_ESTABLISH_IND 12
# define RB_ESTABLISH_CNF 14
# define RB_RELEASE_REQ 15
# define RB_RELEASE_IND 16
# define MEASUREMENT_IND 17
# define CONN_LOSS_IND 18
# define PAGING_REQ 19
# define NOTIFICATION_IND 20
//----------------------------------------------------------
// Constants
//----------------------------------------------------------
// Define max length authorized (to be updated later)
# define NAS_MAX_LENGTH 180 // maximum length of a NAS primitive
# define NAS_TL_SIZE 4 // size of the Type+Length fields of the primitive
# define NAS_DATA_MAX_LENGTH NAS_MAX_LENGTH - NAS_TL_SIZE //remaining bytes for the message
# define MAX_RABS 8 * 64 //NB_RAB_MAX * MAX_MOBILES_PER_RG //27 // = MAXURAB
# define MAX_MEASURE_NB 5
//Connection Establishment status
// UE
# define TERMINATED 0
# define ABORTED 1
# define ALREADY_CONNECTED 2
// RG + RB Establishment Confirm
# define ACCEPTED 0
# define FAILURE 1
//----------------------------------------------------------
// Parameter types
//----------------------------------------------------------
typedef unsigned int nasPeriod_t; // Broadcast repetition period
typedef unsigned short nasBroadcastCategory_t; // identifies the type of data to broadcast (IP signalling/ List of neighbors)
typedef unsigned char nasIMEI_t[14]; // 14 digits of IMEI
typedef unsigned short nasDataLength_t; // Length of the data in the primitive
typedef unsigned short nasCellID_t; // ID of the cell for connection
typedef unsigned int nasLocalConnectionRef_t; // local identifier
typedef unsigned short nasConnectionStatus_t; // connection establishment status
typedef unsigned short nasReleaseCause_t; // connection release cause
typedef unsigned short nasSignalingPriority_t; // priority to use srb3 or srb4
typedef unsigned short nasRadioBearerId_t;
typedef unsigned short nasQoSTrafficClass_t; //QoS traffic class requested
typedef unsigned short nasIPdscp_t; // DSCP code transported to service NAS
typedef struct nasRBDef {
nasRadioBearerId_t rbId;
nasQoSTrafficClass_t QoSclass;
nasIPdscp_t dscp;
} nasrbParms_t;
typedef unsigned int nasSapId_t; // Id of the QoS SAP to use
typedef unsigned short nasRBEstablishStatus_t; // radio bearer establishment status
typedef unsigned short nasNumRBsInList_t; // number of RBs defined in the list
typedef nasrbParms_t nasRBList_t[MAX_RABS]; // List of Rbs for handover
typedef unsigned short nasNumRGsMeas_t; // number of RGs that could be measured
typedef unsigned int nasPagingUEId_t; // Cell_Id of the mobile, = Local Conn Ref
typedef unsigned int nasSigLevel_t; // Signal level measured
typedef struct nasMeasures {
nasCellID_t cell_id;
nasSigLevel_t level;
} nasMeasures_t;
//----------------------------------------------------------
// Primitive definitions
//----------------------------------------------------------
// -- SAP-GC
struct NASInfoBroadcastReq {
nasPeriod_t period; // 0 = one-shot, otherwise in x 10 ms
nasBroadcastCategory_t category;
nasDataLength_t nasDataLength;
};
struct NASInfoBroadcastInd {
nasDataLength_t nasDataLength;
};
struct nas_ue_gc_element {
unsigned short type;
unsigned short length;
union {
struct NASInfoBroadcastInd broadcast_ind;
} nasUEGCPrimitive;
};
struct nas_rg_gc_element {
unsigned short type;
unsigned short length;
union {
struct NASInfoBroadcastReq broadcast_req;
} nasRGGCPrimitive;
};
// -- SAP-DC
struct NASConnEstablishReq {
nasLocalConnectionRef_t localConnectionRef; //provided by NAS
nasCellID_t cellId;
};
struct NASConnEstablishInd {
nasLocalConnectionRef_t localConnectionRef;
nasIMEI_t InterfaceIMEI;
};
struct NASConnEstablishConf {
nasLocalConnectionRef_t localConnectionRef;
nasConnectionStatus_t status; // can be : Accepted, Failure
nasNumRBsInList_t num_RBs; // actual number of RBs in the list
nasRBList_t RB_List;
};
struct NASConnEstablishResp {
nasLocalConnectionRef_t localConnectionRef;
nasIMEI_t InterfaceIMEI;
nasConnectionStatus_t status; // can be : Terminated, Aborted , Already_Connected
};
struct NASConnReleaseReq {
nasLocalConnectionRef_t localConnectionRef;
nasReleaseCause_t releaseCause;
};
struct NASConnReleaseInd {
nasLocalConnectionRef_t localConnectionRef;
nasReleaseCause_t releaseCause;
};
struct NASConnLossInd {
nasLocalConnectionRef_t localConnectionRef;
};
struct NASDataReq {
nasLocalConnectionRef_t localConnectionRef;
nasSignalingPriority_t priority;
nasDataLength_t nasDataLength;
};
struct NASDataInd {
nasLocalConnectionRef_t localConnectionRef;
nasSignalingPriority_t priority;
nasDataLength_t nasDataLength;
};
struct NASrbEstablishReq {
nasLocalConnectionRef_t localConnectionRef;
nasRadioBearerId_t rbId;
nasQoSTrafficClass_t QoSclass;
nasIPdscp_t dscp;
};
struct NASrbEstablishInd {
nasLocalConnectionRef_t localConnectionRef;
nasRadioBearerId_t rbId;
nasQoSTrafficClass_t QoSclass;
nasIPdscp_t dscp;
nasSapId_t sapId;
};
struct NASrbEstablishConf {
nasLocalConnectionRef_t localConnectionRef;
nasRadioBearerId_t rbId;
nasSapId_t sapId;
nasRBEstablishStatus_t status; // can be : Accepted, Failure
};
struct NASrbReleaseReq {
nasLocalConnectionRef_t localConnectionRef;
nasRadioBearerId_t rbId;
};
struct NASrbReleaseInd {
nasLocalConnectionRef_t localConnectionRef;
nasRadioBearerId_t rbId;
};
struct NASMeasureReq {
nasLocalConnectionRef_t localConnectionRef;
};
struct NASMeasureInd {
nasLocalConnectionRef_t localConnectionRef;
nasNumRGsMeas_t nb_rg;
nasMeasures_t measures[MAX_MEASURE_NB];
};
/*****
* UE Primitives
*****/
struct nas_ue_dc_element {
unsigned short type;
unsigned short length;
union {
struct NASConnEstablishReq conn_establish_req;
struct NASConnEstablishResp conn_establish_resp;
// struct NASConnReleaseInd conn_release_ind;
struct NASConnReleaseReq conn_release_req;
struct NASConnLossInd conn_loss_ind;
struct NASDataReq data_transfer_req;
struct NASDataInd data_transfer_ind;
struct NASrbEstablishInd rb_establish_ind;
struct NASrbReleaseInd rb_release_ind;
struct NASMeasureInd measurement_ind;
struct NASMeasureReq measurement_req;
} nasUEDCPrimitive;
};
/*****
* RG Primitives
*****/
struct nas_rg_dc_element {
unsigned short type;
unsigned short length;
union {
struct NASConnEstablishInd conn_establish_ind;
struct NASConnEstablishConf conn_establish_conf;
struct NASConnReleaseInd conn_release_ind;
// struct NASConnReleaseReq conn_release_req;
struct NASConnLossInd conn_loss_ind;
struct NASDataReq data_transfer_req;
struct NASDataInd data_transfer_ind;
struct NASrbEstablishReq rb_establish_req;
struct NASrbEstablishConf rb_establish_conf;
struct NASrbReleaseReq rb_release_req;
} nasRGDCPrimitive;
};
// -- SAP-NT
struct NASPagingReq {
nasPagingUEId_t UeId;
nasDataLength_t nasDataLength;
};
struct NASNotificationInd {
nasDataLength_t nasDataLength;
};
struct nas_ue_nt_element {
unsigned short type;
unsigned short length;
union {
struct NASNotificationInd notification_ind;
} nasUENTPrimitive;
};
struct nas_rg_nt_element {
unsigned short type;
unsigned short length;
union {
struct NASPagingReq paging_req;
} nasRGNTPrimitive;
};
#endif

View File

@@ -1,65 +0,0 @@
/*
* 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
*/
/***************************************************************************
graal_sap.h - description
-------------------
copyright : (C) 2002 by Eurecom
email : michelle.wetterwald@eurecom.fr
yan.moret@eurecom.fr
***************************************************************************
***************************************************************************/
#ifndef _NAS_SAP_H
#define _NAS_SAP_H
// RT-FIFO identifiers ** must be identical to Access Stratum as_sap.h and rrc_sap.h
#define RRC_DEVICE_GC RRC_SAPI_GCSAP
#define RRC_DEVICE_NT RRC_SAPI_NTSAP
#define RRC_DEVICE_DC_INPUT0 RRC_SAPI_DCSAP_IN
#define RRC_DEVICE_DC_OUTPUT0 RRC_SAPI_DCSAP_OUT
//FIFO indexes in control blocks
#define NAS_DC_INPUT_SAPI 0
#define NAS_DC_OUTPUT_SAPI 1
#define NAS_SAPI_CX_MAX 2
#define NAS_GC_SAPI 0
#define NAS_NT_SAPI 1
#define NAS_RAB_INPUT_SAPI 2
#define NAS_RAB_OUTPUT_SAPI 3
#define NAS_SAPI_MAX 4
#endif

View File

@@ -1,888 +0,0 @@
/*
* 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
*/
#include "local.h"
#include "proto_extern.h"
//#include <linux/in.h>
//#include <net/ndisc.h>
//#include <linux/icmpv6.h>
//#include <linux/icmp.h>
//#include <linux/udp.h>
//#include <linux/tcp.h>
//#define NAS_DEBUG_TOOL 1
//---------------------------------------------------------------------------
//
void nas_TOOL_fct(struct classifier_entity *gc, uint8_t fct)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_FCT - begin \n");
#endif
if (gc==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_FCT - input parameter gc is NULL \n");
#endif
return;
}
// End debug information
switch(fct) {
case NAS_FCT_QOS_SEND:
gc->fct=nas_COMMON_QOS_send;
break;
case NAS_FCT_CTL_SEND:
gc->fct=nas_CTL_send;
break;
case NAS_FCT_DC_SEND:
gc->fct=nas_mesh_DC_send_sig_data_request;
break;
case NAS_FCT_DEL_SEND:
gc->fct=nas_COMMON_del_send;
break;
default:
gc->fct=nas_COMMON_del_send;
}
}
//---------------------------------------------------------------------------
uint8_t nas_TOOL_invfct(struct classifier_entity *gc)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_INVFCT - begin \n");
#endif
if (gc==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_INVFCT - input parameter gc is NULL \n");
#endif
return 0;
}
// End debug information
if (gc->fct==nas_COMMON_QOS_send)
return NAS_FCT_QOS_SEND;
if (gc->fct==nas_CTL_send)
return NAS_FCT_CTL_SEND;
if (gc->fct==nas_COMMON_del_send)
return NAS_FCT_DEL_SEND;
if (gc->fct==nas_mesh_DC_send_sig_data_request)
return NAS_FCT_DC_SEND;
return 0;
}
//---------------------------------------------------------------------------
uint8_t nas_TOOL_get_dscp6(struct ipv6hdr *iph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_GET_DSCP6 - begin \n");
#endif
if (iph==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_GET_DSCP6 - input parameter iph is NULL \n");
#endif
return 0;
}
// End debug information
return (ntohl(((*(__u32 *)iph)&NAS_TRAFFICCLASS_MASK)))>>22;
//return ntohs(*(const __be16 *)iph) >> 4; // see linux/dsfield.h
}
//---------------------------------------------------------------------------
uint8_t nas_TOOL_get_dscp4(struct iphdr *iph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_GET_DSCP4 - begin \n");
#endif
if (iph==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_GET_DSCP4 - input parameter iph is NULL \n");
#endif
return 0;
}
// End debug information
return (iph->tos);
}
//---------------------------------------------------------------------------
int nas_TOOL_network6(struct in6_addr *addr, struct in6_addr *prefix, uint8_t plen)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_NETWORK6 - begin \n");
#endif
if (addr==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_NETWORK6 - input parameter addr is NULL \n");
#endif
return 0;
}
if (prefix==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_NETWORK6 - input parameter prefix is NULL \n");
#endif
return 0;
}
// End debug information
switch(plen/32) {
case 0:
return (((addr->s6_addr32[0]>>(32-plen))<<(32-plen))==prefix->s6_addr[0]);
case 1:
return ((addr->s6_addr32[0]==prefix->s6_addr[0])&&
(((addr->s6_addr32[1]>>(64-plen))<<(64-plen))==prefix->s6_addr[1]));
case 2:
return ((addr->s6_addr32[0]==prefix->s6_addr[0])&&
(addr->s6_addr32[1]==prefix->s6_addr[1])&&
(((addr->s6_addr32[2]>>(96-plen))<<(96-plen))==prefix->s6_addr[2]));
case 3:
return ((addr->s6_addr32[0]==prefix->s6_addr[0])&&
(addr->s6_addr32[1]==prefix->s6_addr[1])&&
(addr->s6_addr32[2]==prefix->s6_addr[2])&&
(((addr->s6_addr32[3]>>(128-plen))<<(128-plen))==prefix->s6_addr[3]));
default:
return ((addr->s6_addr32[0]==prefix->s6_addr[0])&&
(addr->s6_addr32[1]==prefix->s6_addr[1])&&
(addr->s6_addr32[2]==prefix->s6_addr[2])&&
(addr->s6_addr32[3]==prefix->s6_addr[3]));
}
}
//---------------------------------------------------------------------------
int nas_TOOL_network4(uint32_t *addr, uint32_t *prefix, uint8_t plen)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_NETWORK4 - begin \n");
#endif
if (addr==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_NETWORK4 - input parameter addr is NULL \n");
#endif
return 0;
}
if (prefix==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_NETWORK4 - input parameter prefix is NULL \n");
#endif
return 0;
}
// End debug information
if (plen>=32)
return (*addr==*prefix);
else
return (((*addr>>(32-plen))<<(32-plen))==*prefix);
}
//---------------------------------------------------------------------------
//struct udphdr *nas_TOOL_get_udp6(struct ipv6hdr *iph){
//---------------------------------------------------------------------------
// return (struct udphdr *)((char *)iph+NAS_IPV6_SIZE); // to modify
//}
//---------------------------------------------------------------------------
uint8_t *nas_TOOL_get_protocol6(struct ipv6hdr *iph, uint8_t *protocol)
{
//---------------------------------------------------------------------------
uint16_t size;
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_GET_PROTOCOL6 - begin \n");
#endif
if (iph==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_GET_PROTOCOL6 - input parameter iph is NULL \n");
#endif
return NULL;
}
if (protocol==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_GET_PROTOCOL6 - input parameter protocol is NULL \n");
#endif
return NULL;
}
// End debug information
*protocol=iph->nexthdr;
size=NAS_IPV6_SIZE;
while (1) {
switch(*protocol) {
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_ICMPV6:
return (uint8_t *)((uint8_t *)iph+size);
case IPPROTO_HOPOPTS:
case IPPROTO_ROUTING:
case IPPROTO_DSTOPTS:
*protocol=((uint8_t *)iph+size)[0];
size+=((uint8_t *)iph+size)[1]*8+8;
break;
case IPPROTO_FRAGMENT:
*protocol=((uint8_t *)iph+size)[0];
size+=((uint8_t *)iph+size)[1]+8;
break;
case IPPROTO_NONE:
case IPPROTO_AH:
case IPPROTO_ESP:
default:
return NULL;
}
}
}
//---------------------------------------------------------------------------
uint8_t *nas_TOOL_get_protocol4(struct iphdr *iph, uint8_t *protocol)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_GET_PROTOCOL4 - begin \n");
#endif
if (iph==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_GET_PROTOCOL4 - input parameter iph is NULL \n");
#endif
return NULL;
}
if (protocol==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_GET_PROTOCOL4 - input parameter protocol is NULL \n");
#endif
return NULL;
}
// End debug information
*protocol=iph->protocol;
switch(*protocol) {
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_ICMP:
return (uint8_t *)((uint8_t *)iph+iph->tot_len);
default:
return NULL;
}
}
//---------------------------------------------------------------------------
// Convert the IMEI to iid
void nas_TOOL_imei2iid(uint8_t *imei, uint8_t *iid)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_IMEI2IID - begin \n");
#endif
if (imei==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_IMEI2IID - input parameter imei is NULL \n");
#endif
return;
}
if (iid==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_IMEI2IID - input parameter iid is NULL \n");
#endif
return;
}
// End debug information
memset(iid, 0, NAS_ADDR_LEN);
iid[0] = 0x03;
iid[1] = 16*imei[0]+imei[1];
iid[2] = 16*imei[2]+imei[3];
iid[3] = 16*imei[4]+imei[5];
iid[4] = 16*imei[6]+imei[7];
iid[5] = 16*imei[8]+imei[9];
iid[6] = 16*imei[10]+imei[11];
iid[7] = 16*imei[12]+imei[13];
}
//struct udphdr *nas_TOOL_get_udp4(struct iphdr *iph)
//{
// return (struct udphdr *)((char *)iph+NAS_IPV4_SIZE); // to modify
//}
//---------------------------------------------------------------------------
char *nas_TOOL_get_udpmsg(struct udphdr *udph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_GET_UDPMSG - begin \n");
#endif
if (udph==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_GET_UDPMSG - input parameter udph is NULL \n");
#endif
return NULL;
}
// End debug information
return ((char *)udph+sizeof(struct udphdr));
}
//---------------------------------------------------------------------------
// Compute the UDP checksum (the data size must be odd)
uint16_t nas_TOOL_udpcksum(struct in6_addr *saddr, struct in6_addr *daddr, uint8_t proto, uint32_t udplen, void *data)
{
//---------------------------------------------------------------------------
uint32_t i;
uint16_t *data16;
uint32_t csum=0;
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_UDPCKSUM - begin \n");
#endif
if (saddr==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_UDPCKSUM - input parameter saddr is NULL \n");
#endif
return 0;
}
if (daddr==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_UDPCKSUM - input parameter daddr is NULL \n");
#endif
return 0;
}
if (data==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_UDPCKSUM - input parameter data is NULL \n");
#endif
return 0;
}
// End debug information
data16=data;
for (i=0; i<8; ++i) {
csum+=ntohs(saddr->s6_addr16[i]);
if (csum>0xffff)
csum-=0xffff;
}
for (i=0; i<8; ++i) {
csum+=ntohs(daddr->s6_addr16[i]);
if (csum>0xffff)
csum-=0xffff;
}
csum+=(udplen>>16); // udplen checksum
if (csum>0xffff)
csum -= 0xffff;
csum+=udplen & 0xffff;
if (csum>0xffff)
csum -= 0xffff;
csum+=proto; // protocol checksum
if (csum>0xffff)
csum-=0xffff;
for (i = 0; 2*i < udplen; i++) {
csum+=ntohs(data16[i]);
if (csum>0xffff)
csum-=0xffff;
}
return htons((uint16_t)(~csum)&0xffff);
}
//---------------------------------------------------------------------------
void print_TOOL_pk_udp(struct udphdr *udph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("PRINT_TOOL_PK_UDP - begin \n");
#endif
if (udph==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_PK_UDP - input parameter udph is NULL \n");
#endif
return;
}
// End debug information
if (udph!=NULL) {
printk("UDP:\t source = %u, dest = %u, len = %u, check = %x\n", ntohs(udph->source), ntohs(udph->dest), ntohs(udph->len), udph->check);
}
}
//---------------------------------------------------------------------------
void print_TOOL_pk_tcp(struct tcphdr *tcph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("PRINT_TOOL_PK_TDP - begin \n");
#endif
if (tcph==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_PK_TDP - input parameter tcph is NULL \n");
#endif
return;
}
// End debug information
if (tcph!=NULL) {
printk("TCP:\t source = %u, dest = %u\n", tcph->source, tcph->dest);
}
}
//---------------------------------------------------------------------------
void print_TOOL_pk_icmp6(struct icmp6hdr *icmph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("PRINT_TOOL_PK_ICMP6 - begin \n");
#endif
if (icmph==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_PK_ICMP6 - input parameter icmph is NULL \n");
#endif
return;
}
// End debug information
if (icmph!=NULL) {
printk("ICMPv6:\t type= %d, code = %d\n", icmph->icmp6_type, icmph->icmp6_code);
switch(icmph->icmp6_type) {
case ICMPV6_DEST_UNREACH:
printk("Destination unreachable\n");
break;
case ICMPV6_PKT_TOOBIG:
printk("Packet too big\n");
break;
case ICMPV6_TIME_EXCEED:
printk("Time exceeded\n");
break;
case ICMPV6_PARAMPROB:
printk("Parameter problem\n");
break;
case ICMPV6_ECHO_REQUEST:
printk("Echo request\n");
break;
case ICMPV6_ECHO_REPLY:
printk("Echo reply\n");
break;
case ICMPV6_MGM_QUERY:
printk("Multicast listener query\n");
break;
case ICMPV6_MGM_REPORT:
printk("Multicast listener report\n");
break;
case ICMPV6_MGM_REDUCTION:
printk("Multicast listener done\n");
break;
case NDISC_ROUTER_SOLICITATION:
printk("Router solicitation\n");
break;
case NDISC_ROUTER_ADVERTISEMENT:
printk("Router advertisment\n");
break;
case NDISC_NEIGHBOUR_SOLICITATION:
printk("Neighbour solicitation\n");
break;
case NDISC_NEIGHBOUR_ADVERTISEMENT:
printk("Neighbour advertisment\n");
break;
case NDISC_REDIRECT:
printk("redirect message\n");
break;
}
}
}
//---------------------------------------------------------------------------
void print_TOOL_pk_ipv6(struct ipv6hdr *iph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("PRINT_TOOL_PK_IPv6 - begin \n");
#endif
if (iph==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_PK_IPv6 - input parameter iph is NULL \n");
#endif
return;
}
// End debug information
if (iph!=NULL) {
// char addr[NAS_INET6_ADDRSTRLEN];
printk("IP:\t version = %u, priority = %u, payload_len = %u\n", iph->version, iph->priority, ntohs(iph->payload_len));
printk("\t fl0 = %u, fl1 = %u, fl2 = %u\n",iph->flow_lbl[0],iph->flow_lbl[1],iph->flow_lbl[2]);
printk("\t next header = %u, hop_limit = %u\n", iph->nexthdr, iph->hop_limit);
// inet_ntop(AF_INET6, (void *)(&iph->saddr), addr, NAS_INET6_ADDRSTRLEN);
// printk("\t saddr = %s",addr);
// inet_ntop(AF_INET6, (void *)(&iph->daddr), addr, NAS_INET6_ADDRSTRLEN);
// printk(", daddr = %s\n",addr);
switch(iph->nexthdr) {
case IPPROTO_UDP:
print_TOOL_pk_udp((struct udphdr *)((char *)iph+sizeof(struct ipv6hdr)));
break;
case IPPROTO_TCP:
print_TOOL_pk_tcp((struct tcphdr *)((char *)iph+sizeof(struct ipv6hdr)));
break;
case IPPROTO_ICMPV6:
print_TOOL_pk_icmp6((struct icmp6hdr *)((char *)iph+sizeof(struct ipv6hdr)));
break;
case IPPROTO_IPV6:
print_TOOL_pk_ipv6((struct ipv6hdr *)((char *)iph+sizeof(struct ipv6hdr)));
break;
default:
printk("Unknown upper layer\n");
}
}
}
//---------------------------------------------------------------------------
void print_TOOL_pk_ipv4(struct iphdr *iph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("PRINT_TOOL_PK_IPv4 - begin \n");
#endif
if (iph==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_PK_IPv4 - input parameter iph is NULL \n");
#endif
return;
}
// End debug information
if (iph!=NULL) {
// char addr[NAS_INET_ADDRSTRLEN];
printk("IP:\t version = %u, IP length = %u\n", iph->version, iph->ihl);
// inet_ntop(AF_INET, (void *)(&iph->saddr), addr, NAS_INET_ADDRSTRLEN);
// printk("\t saddr = %s", addr);
// inet_ntop(AF_INET, (void *)(&iph->saddr), addr, NAS_INET_ADDRSTRLEN);
// printk("\t saddr = %s", addr);
}
}
//---------------------------------------------------------------------------
void print_TOOL_pk_all(struct sk_buff *skb)
{
//---------------------------------------------------------------------------
printk("Skb:\t %p, len = %u\n", skb, skb->len);
//navid: need to calculate the current used space: fixme?
printk("Skb:\t available buf space = %u \n", skb->truesize);
switch (ntohs(skb->protocol)) {
case ETH_P_IPV6:
print_TOOL_pk_ipv6((struct ipv6hdr *)skb_network_header(skb));
break;
case ETH_P_IP:
print_TOOL_pk_ipv4((struct iphdr *)skb_network_header(skb));
break;
}
}
//---------------------------------------------------------------------------
/*int isdigit(char c)
{
switch(c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return 1;
default:
return 0;
}
}*/
/*int nas_TOOL_inet_pton4(char *src, uint32_t *dst)
{
uint32_t val;
int n;
uint8_t c;
uint32_t parts[4];
c = *src;
val=0;
n=0
for (;;)
{
for (;;)
{
if (isdigit(c))
{
val = (val * 10) + c - '0';
c = *++src;
}
else
break;
}
if (c == '.')
{
if (n>4)
return -1;
parts[n]=val;
c = *++src;
++n;
}
else
break;
}
if ((c != '\0')||(n!=3))
return (0);
if ((parts[0] | parts[1] | parts[2] | val) > 256)
return (0);
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
if (dst)
dst = htonl(val);
return (1);
}*/
//---------------------------------------------------------------------------
void print_TOOL_state(uint8_t state)
{
//---------------------------------------------------------------------------
// case NAS_STATE_IDLE:printk(" State NAS_STATE_IDLE\n");return;
// case NAS_STATE_CONNECTED:printk(" State NAS_STATE_CONNECTED\n");return;
// case NAS_STATE_ESTABLISHMENT_REQUEST:printk(" State NAS_STATE_ESTABLISHMENT_REQUEST\n");return;
// case NAS_STATE_ESTABLISHMENT_FAILURE:printk(" State NAS_STATE_ESTABLISHMENT_FAILURE\n");return;
// case NAS_STATE_RELEASE_FAILURE:printk(" State NAS_STATE_RELEASE_FAILURE\n");return;
switch(state) {
case NAS_IDLE:
printk("NAS_IDLE\n");
return;
case NAS_CX_FACH:
printk("NAS_CX_FACH\n");
return;
case NAS_CX_DCH:
printk("NAS_CX_DCH\n");
return;
case NAS_CX_RECEIVED:
printk("NAS_CX_RECEIVED\n");
return;
case NAS_CX_CONNECTING:
printk("NAS_CX_CONNECTING\n");
return;
case NAS_CX_RELEASING:
printk("NAS_CX_RELEASING\n");
return;
case NAS_CX_CONNECTING_FAILURE:
printk("NAS_CX_CONNECTING_FAILURE\n");
return;
case NAS_CX_RELEASING_FAILURE:
printk("NAS_CX_RELEASING_FAILURE\n");
return;
case NAS_RB_ESTABLISHING:
printk("NAS_RB_ESTABLISHING\n");
return;
case NAS_RB_RELEASING:
printk("NAS_RB_RELEASING\n");
return;
case NAS_RB_DCH:
printk("NAS_RB_DCH\n");
return;
default:
printk(" Unknown state\n");
}
}
//-----------------------------------------------------------------------------
// Print the content of a buffer in hexadecimal
void nas_tool_print_buffer(char * buffer,int length)
{
//-----------------------------------------------------------------------------
int i;
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_PRINT_BUFFER - begin \n");
#endif
if (buffer==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_TOOL_PRINT_BUFFER - input parameter buffer is NULL \n");
#endif
return;
}
// End debug information
printk("\nBuffer content: ");
for (i=0; i<length; i++)
printk("-%hx-",buffer[i]);
printk(",\t length %d\n", length);
}
//-----------------------------------------------------------------------------
void nas_print_rb_entity(struct rb_entity *rb)
{
//-----------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("NAS_PRINT_RB_ENTITY - begin \n");
#endif
if (rb==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_PRINT_RB_ENTITY - input parameter rb is NULL \n");
#endif
return;
}
// End debug information
printk("\nrb_entity content: rab_id %d, sapi %d, qos %d, \n", rb->rab_id, rb->sapi, rb->qos);
printk("state %d, retry %d, countimer %d\n",rb->state, rb->retry, rb->countimer);
};
//-----------------------------------------------------------------------------
void nas_print_classifier(struct classifier_entity *gc)
{
//-----------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("NAS_PRINT_GC_ENTITY - begin \n");
#endif
if (gc==NULL) {
#ifdef NAS_DEBUG_TOOL
printk("NAS_PRINT_GC_ENTITY - input parameter gc is NULL \n");
#endif
return;
}
// End debug information
printk("\nClassifier content: classref %d, version %d, splen %d, dplen %d,\n", gc->classref, gc->version, gc->splen, gc->dplen);
printk("protocol %d, sport %d, dport %d, rab_id %d\n", gc->protocol, gc->sport, gc->dport, gc->rab_id);
if (gc->rb != NULL) {
nas_print_rb_entity(gc->rb);
}
};

View File

@@ -1 +0,0 @@
This the driver for the UE when NAS layer is running in the UE (EPC setting).

View File

@@ -1,359 +0,0 @@
/*
* 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
*/
/*! \file common.c
* \brief
* \author Navid Nikaein and Raymond Knopp, Lionel GAUTHIER
* \date 2013
* \version 1.0
* \company Eurecom
* \email: navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
#include "local.h"
#include "proto_extern.h"
#ifndef OAI_NW_DRIVER_USE_NETLINK
#include "rtai_fifos.h"
#endif
#include <linux/inetdevice.h>
#include <net/tcp.h>
#include <net/udp.h>
#define NIPADDR(addr) \
(uint8_t)(addr & 0x000000FF), \
(uint8_t)((addr & 0x0000FF00) >> 8), \
(uint8_t)((addr & 0x00FF0000) >> 16), \
(uint8_t)((addr & 0xFF000000) >> 24)
#define NIP6ADDR(addr) \
ntohs((addr)->s6_addr16[0]), \
ntohs((addr)->s6_addr16[1]), \
ntohs((addr)->s6_addr16[2]), \
ntohs((addr)->s6_addr16[3]), \
ntohs((addr)->s6_addr16[4]), \
ntohs((addr)->s6_addr16[5]), \
ntohs((addr)->s6_addr16[6]), \
ntohs((addr)->s6_addr16[7])
//#define OAI_DRV_DEBUG_SEND
//#define OAI_DRV_DEBUG_RECEIVE
void
ue_ip_common_class_wireless2ip(
sdu_size_t data_lenP,
void *pdcp_sdu_pP,
int instP,
rb_id_t rb_idP) {
//---------------------------------------------------------------------------
struct sk_buff *skb_p = NULL;
ipversion_t *ipv_p = NULL;
ue_ip_priv_t *gpriv_p = netdev_priv(ue_ip_dev[instP]);
unsigned int hard_header_len = 0;
#ifdef OAI_DRV_DEBUG_RECEIVE
int i;
unsigned char *addr_p = 0;
#endif
unsigned char protocol;
struct iphdr *network_header_p = NULL;
#ifdef OAI_DRV_DEBUG_RECEIVE
printk("[UE_IP_DRV][%s] begin RB %d Inst %d Length %d bytes\n",__FUNCTION__, rb_idP,instP,data_lenP);
#endif
skb_p = dev_alloc_skb( data_lenP + 2 );
if(!skb_p) {
printk("[UE_IP_DRV][%s] low on memory\n",__FUNCTION__);
++gpriv_p->stats.rx_dropped;
return;
}
skb_reserve(skb_p,2);
memcpy(skb_put(skb_p, data_lenP), pdcp_sdu_pP,data_lenP);
skb_p->dev = ue_ip_dev[instP];
hard_header_len = ue_ip_dev[instP]->hard_header_len;
skb_set_mac_header(skb_p, 0);
skb_set_network_header(skb_p, hard_header_len);
skb_p->mark = rb_idP;
//printk("[NAC_COMMIN_RECEIVE]: Packet Type %d (%d,%d)",skb_p->pkt_type,PACKET_HOST,PACKET_BROADCAST);
skb_p->pkt_type = PACKET_HOST;
#ifdef OAI_DRV_DEBUG_RECEIVE
printk("[UE_IP_DRV][%s] Receiving packet of size %d from PDCP \n",__FUNCTION__, skb_p->len);
for (i=0; i<skb_p->len; i++) {
printk("%2x ",((unsigned char *)(skb_p->data))[i]);
}
printk("\n");
#endif
#ifdef OAI_DRV_DEBUG_RECEIVE
printk("[UE_IP_DRV][%s] skb_p->data @ %p\n",__FUNCTION__, skb_p->data);
printk("[UE_IP_DRV][%s] skb_p->mac_header @ %p\n",__FUNCTION__, skb_p->mac_header);
#endif
// LG TEST skb_p->ip_summed = CHECKSUM_NONE;
skb_p->ip_summed = CHECKSUM_UNNECESSARY;
ipv_p = (ipversion_t *)((void *)&(skb_p->data[hard_header_len]));
switch (ipv_p->version) {
case 6:
#ifdef OAI_DRV_DEBUG_RECEIVE
printk("[UE_IP_DRV][%s] receive IPv6 message\n",__FUNCTION__);
#endif
skb_set_network_header(skb_p, hard_header_len);
//skb_p->network_header_p = &skb_p->data[hard_header_len];
if (hard_header_len == 0) {
skb_p->protocol = htons(ETH_P_IPV6);
} else {
#ifdef OAI_NW_DRIVER_TYPE_ETHERNET
skb_p->protocol = eth_type_trans(skb_p, ue_ip_dev[instP]);
#else
#endif
}
//printk("Writing packet with protocol %x\n",ntohs(skb_p->protocol));
break;
case 4:
#ifdef OAI_DRV_DEBUG_RECEIVE
//printk("NAS_TOOL_RECEIVE: receive IPv4 message\n");
addr_p = (unsigned char *)&((struct iphdr *)&skb_p->data[hard_header_len])->saddr;
if (addr_p) {
printk("[UE_IP_DRV][%s] Source %d.%d.%d.%d\n",__FUNCTION__, addr_p[0],addr_p[1],addr_p[2],addr_p[3]);
}
addr_p = (unsigned char *)&((struct iphdr *)&skb_p->data[hard_header_len])->daddr;
if (addr_p) {
printk("[UE_IP_DRV][%s] Dest %d.%d.%d.%d\n",__FUNCTION__, addr_p[0],addr_p[1],addr_p[2],addr_p[3]);
}
printk("[UE_IP_DRV][%s] protocol %d\n",__FUNCTION__, ((struct iphdr *)&skb_p->data[hard_header_len])->protocol);
#endif
skb_set_network_header(skb_p, hard_header_len);
//network_header_p = (struct iphdr *)skb_network_header(skb_p);
network_header_p = (struct iphdr *)skb_network_header(skb_p);
protocol = network_header_p->protocol;
#ifdef OAI_DRV_DEBUG_RECEIVE
switch (protocol) {
case IPPROTO_IP:
printk("[UE_IP_DRV][%s] Received Raw IPv4 packet\n",__FUNCTION__);
break;
case IPPROTO_IPV6:
printk("[UE_IP_DRV][%s] Received Raw IPv6 packet\n",__FUNCTION__);
break;
case IPPROTO_ICMP:
printk("[UE_IP_DRV][%s] Received Raw ICMP packet\n",__FUNCTION__);
break;
case IPPROTO_TCP:
printk("[UE_IP_DRV][%s] Received TCP packet\n",__FUNCTION__);
break;
case IPPROTO_UDP:
printk("[UE_IP_DRV][%s] Received UDP packet\n",__FUNCTION__);
break;
default:
break;
}
#endif
if (hard_header_len == 0) {
skb_p->protocol = htons(ETH_P_IP);
}
//printk("[UE_IP_DRV][COMMON] Writing packet with protocol %x\n",ntohs(skb_p->protocol));
break;
default:
printk("[UE_IP_DRV][%s] begin RB %ld Inst %d Length %d bytes\n",__FUNCTION__,rb_idP,instP,data_lenP);
printk("[UE_IP_DRV][%s] Inst %d: receive unknown message (version=%d)\n",__FUNCTION__,instP,ipv_p->version);
}
++gpriv_p->stats.rx_packets;
gpriv_p->stats.rx_bytes += data_lenP;
#ifdef OAI_DRV_DEBUG_RECEIVE
printk("[UE_IP_DRV][%s] sending packet of size %d to kernel\n",__FUNCTION__,skb_p->len);
for (i=0; i<skb_p->len; i++) {
printk("%2x ",((unsigned char *)(skb_p->data))[i]);
}
printk("\n");
#endif //OAI_DRV_DEBUG_RECEIVE
netif_rx_ni(skb_p);
#ifdef OAI_DRV_DEBUG_RECEIVE
printk("[UE_IP_DRV][%s] end\n",__FUNCTION__);
#endif
}
//---------------------------------------------------------------------------
// Delete the data
void ue_ip_common_ip2wireless_drop(struct sk_buff *skb_pP, int instP) {
//---------------------------------------------------------------------------
ue_ip_priv_t *priv_p=netdev_priv(ue_ip_dev[instP]);
++priv_p->stats.tx_dropped;
}
//---------------------------------------------------------------------------
// Request the transfer of data (QoS SAP)
void
ue_ip_common_ip2wireless(
struct sk_buff *skb_pP,
int instP
) {
//---------------------------------------------------------------------------
struct pdcp_data_req_header_s pdcph;
ue_ip_priv_t *priv_p=netdev_priv(ue_ip_dev[instP]);
ipversion_t *ipv_p = NULL;
unsigned int hard_header_len = 0;
unsigned char *src_addr = 0;
unsigned char *dst_addr = 0;
#ifdef LOOPBACK_TEST
int i;
#endif
#ifdef OAI_DRV_DEBUG_SEND
int j;
#endif
unsigned int bytes_wrote;
// Start debug information
#ifdef OAI_DRV_DEBUG_SEND
printk("[UE_IP_DRV][%s] inst %d begin \n",__FUNCTION__,instP);
#endif
if (skb_pP==NULL) {
#ifdef OAI_DRV_DEBUG_SEND
printk("[UE_IP_DRV][%s] input parameter skb is NULL \n",__FUNCTION__);
#endif
return;
}
pdcph.data_size = skb_pP->len;
if (skb_pP->mark) {
pdcph.rb_id = skb_pP->mark;
} else {
pdcph.rb_id = UE_IP_DEFAULT_RAB_ID;
}
pdcph.inst = instP;
//pass source/destination IP addresses to PDCP header
hard_header_len = ue_ip_dev[instP]->hard_header_len;
ipv_p = (ipversion_t *)((void *)&(skb_pP->data[hard_header_len]));
switch (ipv_p->version) {
case 6:
printk("[UE_IP_DRV][%s] receive IPv6 message\n",__FUNCTION__);
//TODO
break;
case 4:
src_addr = (unsigned char *)&((struct iphdr *)&skb_pP->data[hard_header_len])->saddr;
if (src_addr) {
printk("[UE_IP_DRV][%s] Source %d.%d.%d.%d\n",__FUNCTION__, src_addr[0],src_addr[1],src_addr[2],src_addr[3]);
}
dst_addr = (unsigned char *)&((struct iphdr *)&skb_pP->data[hard_header_len])->daddr;
if (dst_addr) {
printk("[UE_IP_DRV][%s] Dest %d.%d.%d.%d\n",__FUNCTION__, dst_addr[0],dst_addr[1],dst_addr[2],dst_addr[3]);
}
//get Ipv4 address and pass to PCDP header
printk("[UE_IP_DRV] source Id: 0x%08x\n",pdcph.sourceL2Id );
printk("[UE_IP_DRV] destinationL2Id Id: 0x%08x\n",pdcph.destinationL2Id );
pdcph.sourceL2Id = ntohl( ((struct iphdr *)&skb_pP->data[hard_header_len])->saddr) & 0x00FFFFFF;
pdcph.destinationL2Id = ntohl( ((struct iphdr *)&skb_pP->data[hard_header_len])->daddr) & 0x00FFFFFF;
break;
default:
break;
}
bytes_wrote = ue_ip_netlink_send((char *)&pdcph,UE_IP_PDCPH_SIZE);
#ifdef OAI_DRV_DEBUG_SEND
printk("[UE_IP_DRV][%s] Wrote %d bytes (header for %d byte skb) to PDCP via netlink\n",__FUNCTION__,
bytes_wrote,skb_pP->len);
#endif
if (bytes_wrote != UE_IP_PDCPH_SIZE) {
printk("[UE_IP_DRV][%s] problem while writing PDCP's header (bytes wrote = %d)\n",__FUNCTION__,bytes_wrote);
printk("rb_id %ld, Wrote %d, Header Size %d \n", pdcph.rb_id, bytes_wrote, UE_IP_PDCPH_SIZE);
priv_p->stats.tx_dropped ++;
return;
}
bytes_wrote += ue_ip_netlink_send((char *)skb_pP->data,skb_pP->len);
if (bytes_wrote != skb_pP->len+UE_IP_PDCPH_SIZE) {
printk("[UE_IP_DRV][%s] Inst %d, RB_ID %ld: problem while writing PDCP's data, bytes_wrote = %d, Data_len %d, PDCPH_SIZE %d\n",
__FUNCTION__,
instP,
pdcph.rb_id,
bytes_wrote,
skb_pP->len,
UE_IP_PDCPH_SIZE); // congestion
priv_p->stats.tx_dropped ++;
return;
}
#ifdef OAI_DRV_DEBUG_SEND
printk("[UE_IP_DRV][%s] Sending packet of size %d to PDCP \n",__FUNCTION__,skb_pP->len);
for (j=0; j<skb_pP->len; j++) {
printk("%2x ",((unsigned char *)(skb_pP->data))[j]);
}
printk("\n");
#endif
priv_p->stats.tx_bytes += skb_pP->len;
priv_p->stats.tx_packets ++;
#ifdef OAI_DRV_DEBUG_SEND
printk("[UE_IP_DRV][%s] end \n",__FUNCTION__);
#endif
}
//---------------------------------------------------------------------------
void ue_ip_common_wireless2ip(struct nlmsghdr *nlh_pP) {
//---------------------------------------------------------------------------
struct pdcp_data_ind_header_s *pdcph_p = (struct pdcp_data_ind_header_s *)NLMSG_DATA(nlh_pP);
ue_ip_priv_t *priv_p;
priv_p = netdev_priv(ue_ip_dev[pdcph_p->inst]);
#ifdef OAI_DRV_DEBUG_RECEIVE
printk("[UE_IP_DRV][%s] QOS receive from PDCP, size %d, rab %d, inst %d\n",__FUNCTION__,
pdcph_p->data_size,pdcph_p->rb_id,pdcph_p->inst);
#endif
ue_ip_common_class_wireless2ip(pdcph_p->data_size,
(unsigned char *)NLMSG_DATA(nlh_pP) + UE_IP_PDCPH_SIZE,
pdcph_p->inst,
pdcph_p->rb_id);
}

View File

@@ -1,59 +0,0 @@
/*
* 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
*/
#include "common/openairinterface5g_limits.h"
#ifndef _UE_IP_CST
#define _UE_IP_CST
#define UE_IP_MAX_LENGTH 180
// General Constants
#define UE_IP_MTU 1500
#define UE_IP_TX_QUEUE_LEN 100
#define UE_IP_ADDR_LEN 8
#define UE_IP_INET6_ADDRSTRLEN 46
#define UE_IP_INET_ADDRSTRLEN 16
#define UE_IP_DEFAULT_RAB_ID 1
#define UE_IP_RESET_RX_FLAGS 0
#define UE_IP_RETRY_LIMIT_DEFAULT (int)5
#define UE_IP_MESSAGE_MAXLEN (int)5004
#define UE_IP_TIMER_ESTABLISHMENT_DEFAULT (int)12
#define UE_IP_TIMER_RELEASE_DEFAULT (int)2
#define UE_IP_TIMER_IDLE UINT_MAX
#define UE_IP_TIMER_TICK HZ
#define UE_IP_PDCPH_SIZE (int)sizeof(struct pdcp_data_req_header_s)
#define UE_IP_IPV4_SIZE (int)20
#define UE_IP_IPV6_SIZE (int)40
#define UE_IP_NB_INSTANCES_MAX NUMBER_OF_UE_MAX /*MAX_MOBILES_PER_ENB*/
#endif

View File

@@ -1,442 +0,0 @@
/*
* 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
*/
/*! \file device.c
* \brief Networking Device Driver for OpenAirInterface
* \author navid nikaein, Lionel Gauthier, raymond knopp
* \company Eurecom
* \email: raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#include "constant.h"
#include "local.h"
#include "proto_extern.h"
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/moduleparam.h>
#include <asm/io.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/delay.h>
#include <asm/unistd.h>
#include <linux/netdevice.h>
struct net_device *ue_ip_dev[UE_IP_NB_INSTANCES_MAX];
#ifdef OAI_NW_DRIVER_USE_NETLINK
extern void ue_ip_netlink_release(void);
extern int ue_ip_netlink_init(void);
#endif
//---------------------------------------------------------------------------
int ue_ip_find_inst(struct net_device *dev_pP) {
//---------------------------------------------------------------------------
int i;
for (i=0; i<UE_IP_NB_INSTANCES_MAX; i++)
if (ue_ip_dev[i] == dev_pP) {
return(i);
}
return(-1);
}
//---------------------------------------------------------------------------
#ifndef OAI_NW_DRIVER_USE_NETLINK
void *ue_ip_interrupt(void) {
//---------------------------------------------------------------------------
uint8_t cxi;
// ue_ip_priv_t *priv_p=netdev_priv(dev_id);
// unsigned int flags;
// priv_p->lock = SPIN_LOCK_UNLOCKED;
#ifdef OAI_DRV_DEBUG_INTERRUPT
printk("INTERRUPT - begin\n");
#endif
// spin_lock_irqsave(&priv_p->lock,flags);
cxi=0;
// mesh_GC_receive();
// mesh_DC_receive(naspriv->cx+cxi);
#ifndef OAI_NW_DRIVER_USE_NETLINK
ue_ip_common_wireless2ip();
#endif
// spin_unlock_irqrestore(&priv_p->lock,flags);
#ifdef OAI_DRV_DEBUG_INTERRUPT
printk("INTERRUPT: end\n");
#endif
// return 0;
}
#endif //NETLINK
//---------------------------------------------------------------------------
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
void ue_ip_timer(struct timer_list *t)
#else
void ue_ip_timer(unsigned long dataP)
#endif
{
//---------------------------------------------------------------------------
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
ue_ip_priv_t *priv_p = from_timer(priv_p, t, timer);
#else
ue_ip_priv_t *priv_p = (ue_ip_priv_t *)dataP;
#endif
spin_lock(&priv_p->lock);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
mod_timer(&priv_p->timer, jiffies + UE_IP_TIMER_TICK);
#else
(priv_p->timer).function = ue_ip_timer;
(priv_p->timer).expires = jiffies + UE_IP_TIMER_TICK;
(priv_p->timer).data = dataP;
add_timer(&priv_p->timer);
#endif
spin_unlock(&priv_p->lock);
return;
// add_timer(&gpriv->timer);
// spin_unlock(&gpriv->lock);
}
//---------------------------------------------------------------------------
// Called by ifconfig when the device is activated by ifconfig
int ue_ip_open(struct net_device *dev_pP) {
//---------------------------------------------------------------------------
ue_ip_priv_t *priv_p=netdev_priv(dev_pP);
// Address has already been set at init
#ifndef OAI_NW_DRIVER_USE_NETLINK
if (pdcp_2_ue_ip_irq==-EBUSY) {
printk("[UE_IP_DRV][%s] : irq failure\n", __FUNCTION__);
return -EBUSY;
}
#endif //OAI_NW_DRIVER_USE_NETLINK
if(!netif_queue_stopped(dev_pP)) {
netif_start_queue(dev_pP);
} else {
netif_wake_queue(dev_pP);
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
timer_setup(&(priv_p->timer), ue_ip_timer, 0);
(priv_p->timer).expires = jiffies+UE_IP_TIMER_TICK;
#else
init_timer(&priv_p->timer);
(priv_p->timer).expires = jiffies+UE_IP_TIMER_TICK;
(priv_p->timer).data = (unsigned long)priv_p;
(priv_p->timer).function = ue_ip_timer;
#endif
//add_timer(&priv_p->timer);
printk("[UE_IP_DRV][%s] name = %s\n", __FUNCTION__, dev_pP->name);
return 0;
}
//---------------------------------------------------------------------------
// Called by ifconfig when the device is desactivated
int ue_ip_stop(struct net_device *dev_pP) {
//---------------------------------------------------------------------------
ue_ip_priv_t *priv_p = netdev_priv(dev_pP);
printk("[UE_IP_DRV][%s] Begin\n", __FUNCTION__);
del_timer(&(priv_p->timer));
netif_stop_queue(dev_pP);
// MOD_DEC_USE_COUNT;
printk("[UE_IP_DRV][%s] End\n", __FUNCTION__);
return 0;
}
//---------------------------------------------------------------------------
void ue_ip_teardown(struct net_device *dev_pP) {
//---------------------------------------------------------------------------
ue_ip_priv_t *priv_p;
int inst;
printk("[UE_IP_DRV][%s] Begin\n", __FUNCTION__);
if (dev_pP) {
priv_p = netdev_priv(dev_pP);
inst = ue_ip_find_inst(dev_pP);
if ((inst<0) || (inst>=UE_IP_NB_INSTANCES_MAX)) {
printk("[UE_IP_DRV][%s] ERROR, couldn't find instance\n", __FUNCTION__);
return;
}
printk("[UE_IP_DRV][%s] End\n", __FUNCTION__);
} // check dev_pP
else {
printk("[UE_IP_DRV][%s] Device is null\n", __FUNCTION__);
}
}
//---------------------------------------------------------------------------
int ue_ip_set_config(struct net_device *dev_pP, struct ifmap *map_pP) {
//---------------------------------------------------------------------------
printk("[UE_IP_DRV][%s] Begin\n", __FUNCTION__);
if (dev_pP->flags & IFF_UP) {
return -EBUSY;
}
if (map_pP->base_addr != dev_pP->base_addr) {
printk(KERN_WARNING "[UE_IP_DRV][%s] Can't change I/O address\n", __FUNCTION__);
return -EOPNOTSUPP;
}
if (map_pP->irq != dev_pP->irq) {
dev_pP->irq = map_pP->irq;
}
printk("[UE_IP_DRV][%s] End\n", __FUNCTION__);
return 0;
}
//---------------------------------------------------------------------------
//
int ue_ip_hard_start_xmit(struct sk_buff *skb_pP, struct net_device *dev_pP) {
//---------------------------------------------------------------------------
int inst;
if (dev_pP) {
inst = ue_ip_find_inst(dev_pP);
} else {
printk("[UE_IP_DRV][%s] ERROR, device is null\n", __FUNCTION__);
return -1;
}
if ((inst>=0) && (inst<UE_IP_NB_INSTANCES_MAX)) {
#ifdef OAI_DRV_OAI_DRV_DEBUG_DEVICE
printk("[UE_IP_DRV][%s] inst %d, begin\n", __FUNCTION__,inst);
#endif
if (!skb_pP) {
printk("[UE_IP_DRV][%s] input parameter skb is NULL\n", __FUNCTION__);
return -1;
}
// End debug information
netif_stop_queue(dev_pP);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) \
|| (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796 && RHEL_RELEASE_CODE != 2403)
netif_trans_update(dev_pP);
#else
dev_pP->trans_start = jiffies;
#endif
#ifdef OAI_DRV_DEBUG_DEVICE
printk("[UE_IP_DRV][%s] step 1\n", __FUNCTION__);
#endif
ue_ip_common_ip2wireless(skb_pP,inst);
#ifdef OAI_DRV_DEBUG_DEVICE
printk("[UE_IP_DRV][%s] step 2\n", __FUNCTION__);
#endif
dev_kfree_skb(skb_pP);
#ifdef OAI_DRV_DEBUG_DEVICE
printk("[UE_IP_DRV][%s] step 3\n", __FUNCTION__);
#endif
netif_wake_queue(dev_pP);
#ifdef OAI_DRV_DEBUG_DEVICE
printk("[UE_IP_DRV][%s] end\n", __FUNCTION__);
#endif
} else {
printk("[UE_IP_DRV][%s] ERROR, couldn't find instance\n", __FUNCTION__);
return(-1);
}
return 0;
}
//---------------------------------------------------------------------------
struct net_device_stats *ue_ip_get_stats(struct net_device *dev_pP) {
//---------------------------------------------------------------------------
ue_ip_priv_t *priv_p = netdev_priv(dev_pP);
return &priv_p->stats;
}
//---------------------------------------------------------------------------
int ue_ip_set_mac_address(struct net_device *dev_pP, void *mac_pP) {
//---------------------------------------------------------------------------
//struct sockaddr *addr = mac_pP;
printk("[UE_IP_DRV][%s] CHANGE MAC ADDRESS UNSUPPORTED\n", __FUNCTION__);
//memcpy(dev_pP->dev_addr, addr->sa_data, dev_pP->addr_len);
return 0;
}
//---------------------------------------------------------------------------
int ue_ip_change_mtu(struct net_device *dev_pP, int mtuP) {
//---------------------------------------------------------------------------
printk("[UE_IP_DRV][%s] CHANGE MTU %d bytes\n", __FUNCTION__, mtuP);
if ((mtuP<50) || (mtuP>1500)) {
return -EINVAL;
}
dev_pP->mtu = mtuP;
return 0;
}
//---------------------------------------------------------------------------
void ue_ip_change_rx_flags(struct net_device *dev_pP, int flagsP) {
//---------------------------------------------------------------------------
ue_ip_priv_t *priv_p = netdev_priv(dev_pP);
printk("[UE_IP_DRV][%s] CHANGE RX FLAGS %08X\n", __FUNCTION__, flagsP);
priv_p->rx_flags ^= flagsP;
}
//---------------------------------------------------------------------------
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE == 2055)
void ue_ip_tx_timeout(struct net_device *dev_pP, unsigned int txqueue)
#else
void ue_ip_tx_timeout(struct net_device *dev_pP)
#endif
{
//---------------------------------------------------------------------------
// Transmitter timeout, serious problems.
ue_ip_priv_t *priv_p = netdev_priv(dev_pP);
printk("[UE_IP_DRV][%s] begin\n", __FUNCTION__);
// (ue_ip_priv_t *)(dev_pP->priv_p)->stats.tx_errors++;
(priv_p->stats).tx_errors++;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) \
|| (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796 && RHEL_RELEASE_CODE != 2403)
netif_trans_update(dev_pP);
#else
dev_pP->trans_start = jiffies;
#endif
netif_wake_queue(dev_pP);
printk("[UE_IP_DRV][%s] transmit timed out %s\n", __FUNCTION__,dev_pP->name);
}
static const struct net_device_ops ue_ip_netdev_ops = {
.ndo_open = ue_ip_open,
.ndo_stop = ue_ip_stop,
.ndo_start_xmit = ue_ip_hard_start_xmit,
.ndo_validate_addr = NULL,
.ndo_get_stats = ue_ip_get_stats,
.ndo_set_mac_address = ue_ip_set_mac_address,
.ndo_set_config = ue_ip_set_config,
.ndo_do_ioctl = NULL,
#if defined(RHEL_RELEASE_CODE)
#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7, 5)) && (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8, 0))
.extended.ndo_change_mtu = ue_ip_change_mtu,
#else
.ndo_change_mtu = ue_ip_change_mtu,
#endif
#else
.ndo_change_mtu = ue_ip_change_mtu,
#endif
.ndo_tx_timeout = ue_ip_tx_timeout,
.ndo_change_rx_flags = ue_ip_change_rx_flags,
};
/*.ndo_set_multicast_list = NULL,*/
//---------------------------------------------------------------------------
// Initialisation of the network device
void ue_ip_init(struct net_device *dev_pP) {
//---------------------------------------------------------------------------
ue_ip_priv_t *priv_p = NULL;
if (dev_pP) {
priv_p = netdev_priv(dev_pP);
memset(priv_p, 0, sizeof(ue_ip_priv_t));
spin_lock_init(&priv_p->lock);
dev_pP->netdev_ops = &ue_ip_netdev_ops;
dev_pP->hard_header_len = 0;
dev_pP->addr_len = UE_IP_ADDR_LEN;
dev_pP->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP;
dev_pP->tx_queue_len = UE_IP_TX_QUEUE_LEN;
dev_pP->mtu = UE_IP_MTU;
} else {
printk("[UE_IP_DRV][%s] ERROR, Device is NULL!!\n", __FUNCTION__);
return;
}
}
//---------------------------------------------------------------------------
int init_module (void) {
//---------------------------------------------------------------------------
int err,inst;
char devicename[100];
// Initialize parameters shared with RRC
printk("[UE_IP_DRV][%s] Starting OAI IP driver", __FUNCTION__);
for (inst=0; inst<UE_IP_NB_INSTANCES_MAX; inst++) {
printk("[UE_IP_DRV][%s] begin init instance %d\n", __FUNCTION__,inst);
sprintf(devicename,"oip%d",inst+1);
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
ue_ip_dev[inst] = alloc_netdev(sizeof(ue_ip_priv_t),devicename, ue_ip_init);
#else
ue_ip_dev[inst] = alloc_netdev(sizeof(ue_ip_priv_t),devicename, NET_NAME_PREDICTABLE,ue_ip_init);
#endif
//netif_stop_queue(ue_ip_dev[inst]);
if (ue_ip_dev[inst] == NULL) {
printk("[UE_IP_DRV][%s][INST %02d] alloc_netdev FAILED\n", __FUNCTION__,inst);
} else {
// linux/net/core/dev.c line 4767
err= register_netdev(ue_ip_dev[inst]);
if (err) {
printk("[UE_IP_DRV][%s] (inst %d): error %i registering device %s\n", __FUNCTION__, inst,err, ue_ip_dev[inst]->name);
} else {
printk("[UE_IP_DRV][%s] registering device %s, ifindex = %d\n\n", __FUNCTION__,ue_ip_dev[inst]->name, ue_ip_dev[inst]->ifindex);
}
}
}
printk("[UE_IP_DRV][%s] NETLINK INIT\n", __FUNCTION__);
if ((err=ue_ip_netlink_init()) == -1) {
printk("[UE_IP_DRV][%s] NETLINK failed\n", __FUNCTION__);
}
return err;
}
//---------------------------------------------------------------------------
void cleanup_module(void) {
//---------------------------------------------------------------------------
int inst;
printk("[UE_IP_DRV][CLEANUP] begin\n");
for (inst=0; inst<UE_IP_NB_INSTANCES_MAX; inst++) {
#ifdef OAI_DRV_DEBUG_DEVICE
printk("[UE_IP_DRV][CLEANUP] unregister and free net device instance %d\n",inst);
#endif
if (ue_ip_dev[inst]) {
unregister_netdev(ue_ip_dev[inst]);
ue_ip_teardown(ue_ip_dev[inst]);
free_netdev(ue_ip_dev[inst]);
}
}
ue_ip_netlink_release();
printk("[UE_IP_DRV][CLEANUP] end\n");
}
#define DRV_NAME "ue_ip"
#define DRV_VERSION "1.0"DRV_NAME
#define DRV_DESCRIPTION "OPENAIR UE IP Device Driver"
#define DRV_COPYRIGHT "-Copyright(c) GNU GPL Eurecom 2013"
#define DRV_AUTHOR "Lionel GAUTHIER: <firstname.name@eurecom.fr>"DRV_COPYRIGHT

View File

@@ -1,107 +0,0 @@
/*
* 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
*/
/***************************************************************************
local.h - description
-------------------
copyright : (C) 2002 by Eurecom
email : navid.nikaein@eurecom.fr
lionel.gauthier@eurecom.fr,
knopp@eurecom.fr
***************************************************************************/
#ifndef UE_IP_LOCAL_H
#define UE_IP_LOCAL_H
#include <linux/if_arp.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/ipv6.h>
#include <linux/ip.h>
#include <linux/sysctl.h>
#include <linux/timer.h>
#include <linux/unistd.h>
#include <asm/param.h>
//#include <sys/sysctl.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
#include <linux/in.h>
#include <net/ndisc.h>
#include "constant.h"
#include "common/platform_types.h"
#include "sap.h"
typedef struct ue_ip_priv_s {
int irq;
int rx_flags;
struct timer_list timer;
spinlock_t lock;
struct net_device_stats stats;
uint8_t retry_limit;
uint32_t timer_establishment;
uint32_t timer_release;
struct sock *nl_sk;
uint8_t nlmsg[UE_IP_PRIMITIVE_MAX_LENGTH+sizeof(struct nlmsghdr)];
uint8_t xbuffer[UE_IP_PRIMITIVE_MAX_LENGTH]; // transmission buffer
uint8_t rbuffer[UE_IP_PRIMITIVE_MAX_LENGTH]; // reception buffer
} ue_ip_priv_t;
typedef struct ipversion_s {
#if defined(__LITTLE_ENDIAN_BITFIELD)
uint8_t reserved:4,
version:4;
#else
uint8_t version:4,
reserved:4;
#endif
} ipversion_t;
typedef struct pdcp_data_req_header_s {
rb_id_t rb_id;
sdu_size_t data_size;
signed int inst;
ip_traffic_type_t traffic_type;
uint32_t sourceL2Id;
uint32_t destinationL2Id;
} pdcp_data_req_header_t;
typedef struct pdcp_data_ind_header_s {
rb_id_t rb_id;
sdu_size_t data_size;
signed int inst;
ip_traffic_type_t dummy_traffic_type;
uint32_t sourceL2Id;
uint32_t destinationL2Id;
} pdcp_data_ind_header_t;
extern struct net_device *ue_ip_dev[UE_IP_NB_INSTANCES_MAX];
#endif

View File

@@ -1,204 +0,0 @@
/*
* 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
*/
/*! \file netlink.c
* \brief establish a netlink
* \author Navid Nikaein, Lionel Gauthier, Raymond knopp
* \company Eurecom
* \email: navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr, knopp@eurecom.fr
*/
//#include <linux/config.h>
#include <linux/socket.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netlink.h>
#include <net/sock.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
#include <linux/version.h>
#include "local.h"
#include "proto_extern.h"
MODULE_LICENSE("OAI");
#define OAI_IP_DRIVER_NETLINK_ID 31
#define NL_DEST_PID 1
/*******************************************************************************
Prototypes
*******************************************************************************/
static inline void nasmesh_lock(void);
static inline void nasmesh_unlock(void);
static void nas_nl_data_ready (struct sk_buff *skb);
int ue_ip_netlink_init(void);
static struct sock *nas_nl_sk = NULL;
static int exit_netlink_thread=0;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
struct netlink_kernel_cfg cfg = {
.input = nas_nl_data_ready,
};
#endif
static DEFINE_MUTEX(nasmesh_mutex);
static inline void nasmesh_lock(void)
{
mutex_lock(&nasmesh_mutex);
}
static inline void nasmesh_unlock(void)
{
mutex_unlock(&nasmesh_mutex);
}
// This can also be implemented using thread to get the data from PDCP without blocking.
static void nas_nl_data_ready (struct sk_buff *skb)
{
// wake_up_interruptible(skb->sk->sk_sleep);
//nasmesh_lock();
//netlink_rcv_skb(skb, &my_rcv_msg);// my_rcv_msg is the call back func>
//nasmesh_unlock();
struct nlmsghdr *nlh = NULL;
if (skb) {
#ifdef NETLINK_DEBUG
printk("[UE_IP_DRV][NETLINK] Received socket from PDCP\n");
#endif //NETLINK_DEBUG
nlh = (struct nlmsghdr *)skb->data;
ue_ip_common_wireless2ip(nlh);
//kfree_skb(skb); // not required,
}
}
int ue_ip_netlink_init(void)
{
printk("[UE_IP_DRV][NETLINK] Running init ...\n");
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
cfg.groups = 0;
cfg.input = nas_nl_data_ready;
cfg.cb_mutex = &nasmesh_mutex;
cfg.bind = NULL;
nas_nl_sk = netlink_kernel_create(
&init_net,
OAI_IP_DRIVER_NETLINK_ID,
# if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
THIS_MODULE,
# endif
&cfg);
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */
nas_nl_sk = netlink_kernel_create(
&init_net,
OAI_IP_DRIVER_NETLINK_ID,
0,
nas_nl_data_ready,
&nasmesh_mutex, // NULL
THIS_MODULE);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */
if (nas_nl_sk == NULL) {
printk("[UE_IP_DRV][NETLINK] netlink_kernel_create failed \n");
return(-1);
}
return(0);
}
void ue_ip_netlink_release(void)
{
exit_netlink_thread=1;
printk("[UE_IP_DRV][NETLINK] Releasing netlink socket\n");
if(nas_nl_sk) {
netlink_kernel_release(nas_nl_sk); //or skb->sk
}
// printk("[UE_IP_DRV][NETLINK] Removing netlink_rx_thread\n");
//kthread_stop(netlink_rx_thread);
}
int ue_ip_netlink_send(unsigned char *data,unsigned int len)
{
struct sk_buff *nl_skb = alloc_skb(NLMSG_SPACE(len),GFP_ATOMIC);
struct nlmsghdr *nlh = (struct nlmsghdr *)nl_skb->data;
int status;
// printk("[UE_IP_DRV][NETLINK] Sending %d bytes (%d)\n",len,NLMSG_SPACE(len));
skb_put(nl_skb, NLMSG_SPACE(len));
memcpy(NLMSG_DATA(nlh),data,len);
nlh->nlmsg_len = NLMSG_SPACE(len);
nlh->nlmsg_pid = 0; /* from kernel */
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
NETLINK_CB(nl_skb).pid = 0;
#endif
#ifdef NETLINK_DEBUG
printk("[UE_IP_DRV][NETLINK] In nas_netlink_send, nl_skb %p, nl_sk %x, nlh %p, nlh->nlmsg_len %d\n",nl_skb,nas_nl_sk,nlh,nlh->nlmsg_len);
#endif //DEBUG_NETLINK
if (nas_nl_sk) {
// nasmesh_lock();
status = netlink_unicast(nas_nl_sk, nl_skb, NL_DEST_PID, MSG_DONTWAIT);
// mutex_unlock(&nasmesh_mutex);
if (status < 0) {
printk("[UE_IP_DRV][NETLINK] SEND status is %d\n",status);
return(0);
} else {
#ifdef NETLINK_DEBUG
printk("[UE_IP_DRV][NETLINK] SEND status is %d\n",status);
#endif
return len;
}
} else {
printk("[UE_IP_DRV][SEND] socket is NULL\n");
return(0);
}
}

View File

@@ -1,139 +0,0 @@
/*
* 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
*/
/***************************************************************************
proto_extern.h - description
-------------------
copyright : (C) 2002 by Eurecom
email : navid.nikaein@eurecom.fr
lionel.gauthier@eurecom.fr
knopp@eurecom.fr
***************************************************************************/
#ifndef _UE_IP_PROTO_H
#define _UE_IP_PROTO_H
#include <linux/if_arp.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/ipv6.h>
#include <linux/ip.h>
#include <linux/sysctl.h>
#include <linux/timer.h>
#include <asm/param.h>
//#include <sys/sysctl.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
#include <linux/in.h>
#include <net/ndisc.h>
#include "local.h"
// device.c
/** @defgroup _ue_ip_impl_ OAI Network Device for RRC Lite
* @ingroup _ref_implementation_
* @{
\fn int ue_ip_find_inst(struct net_device *dev)
\brief This function determines the instance id for a particular device pointer.
@param dev Pointer to net_device structure
*/
int ue_ip_find_inst(struct net_device *dev);
// common.c
/**
\fn void ue_ip_common_class_wireless2ip(unsigned short dlen, void* pdcp_sdu,int inst,struct classifier_entity *rclass,OaiNwDrvRadioBearerId_t rb_id)
\brief Receive classified LTE packet, build skbuff struct with it and deliver it to the OS network layer.
@param dlen Length of SDU in bytes
@param pdcp_sdu Pointer to received SDU
@param inst Instance number
@param rb_id Radio Bearer Id
*/
void ue_ip_common_class_wireless2ip(sdu_size_t dlen,
void *pdcp_sdu,
int inst,
rb_id_t rb_id);
/**
\fn void ue_ip_common_ip2wireless(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,int inst)
\brief Request the transfer of data (QoS SAP)
@param skb pointer to socket buffer
@param inst device instance
*/
void ue_ip_common_ip2wireless(struct sk_buff *skb, int inst);
/**
\fn void ue_ip_common_ip2wireless_drop(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,int inst)
\brief Drop the IP packet comming from the OS network layer.
@param skb pointer to socket buffer
@param inst device instance
*/
void ue_ip_common_ip2wireless_drop(struct sk_buff *skb, int inst);
#ifndef OAI_NW_DRIVER_USE_NETLINK
/**
\fn void ue_ip_common_wireless2ip()
\brief Retrieve PDU from PDCP through RT-fifos for delivery to the IP stack.
*/
void ue_ip_common_wireless2ip(void);
#else
/**
\fn void ue_ip_common_wireless2ip(struct nlmsghdr *nlh)
\brief Retrieve PDU from PDCP through netlink sockets for delivery to the IP stack.
*/
void ue_ip_common_wireless2ip(struct nlmsghdr *nlh);
#endif //OAI_NW_DRIVER_USE_NETLINK
#ifdef OAI_NW_DRIVER_USE_NETLINK
/**
\fn int ue_ip_netlink_send(unsigned char *data,unsigned int len)
\brief Request the transfer of data by PDCP via netlink socket
@param data pointer to SDU
@param len length of SDU in bytes
@returns Numeber of bytes transfered by netlink socket
*/
int ue_ip_netlink_send(unsigned char *data,unsigned int len);
/**
\fn void ue_ip_COMMON_QOS_receive(struct nlmsghdr *nlh)
\brief Request a PDU from PDCP
@param nlh pointer to netlink message header
*/
void ue_ip_COMMON_QOS_receive(struct nlmsghdr *nlh);
#endif //OAI_NW_DRIVER_USE_NETLINK
// netlink.c
void ue_ip_netlink_release(void);
int ue_ip_netlink_init(void);
/** @} */
#endif

View File

@@ -1,28 +0,0 @@
/*
* 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
*/
#ifndef UE_IP_SAP_H
#define UE_IP_SAP_H
typedef unsigned short OaiNwDrvRadioBearerId_t;
#define UE_IP_PRIMITIVE_MAX_LENGTH 180 // maximum length of a NAS primitive
#endif

View File

@@ -68,7 +68,6 @@
#include "NR_UE-CapabilityRAT-Container.h"
#include "RRC/NAS/nas_config.h"
#include "RRC/NAS/rb_config.h"
#if ENABLE_RAL
#include "rrc_UE_ral.h"
#endif
@@ -766,23 +765,20 @@ rrc_ue_establish_drb(
ip_addr_offset4 = 1;
LOG_I(OIP,"[UE %d] trying to bring up the OAI interface %d, IP X.Y.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP,
ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1);
oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP+1, // interface_id
UE_NAS_USE_TUN?1:(ip_addr_offset3+ue_mod_idP+1), // third_octet
ip_addr_offset4+ue_mod_idP+1, // fourth_octet
"oip"); // interface suffix (when using kernel module)
char ip[20];
snprintf(ip,
sizeof(ip),
"10.0.%d.%d",
UE_NAS_USE_TUN ? 1 : (ip_addr_offset3 + ue_mod_idP + 1),
ip_addr_offset4 + ue_mod_idP + 1);
oip_ifup = nas_config(ip_addr_offset3 + ue_mod_idP + 1, AF_INET, ip, "oaitun_oip");
if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB
LOG_I(OIP,"[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n",
ue_mod_idP,
ip_addr_offset3+ue_mod_idP,
(long int)((eNB_index * LTE_maxDRB) + DRB_config->drb_Identity));
rb_conf_ipv4(0,//add
ue_mod_idP,//cx align with the UE index
ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index
(eNB_index * LTE_maxDRB) + DRB_config->drb_Identity,//rb
0,//dscp
ipv4_address(ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1),//saddr
ipv4_address(ip_addr_offset3+ue_mod_idP+1,eNB_index+1));//daddr
AssertFatal(false, "not implemented\n");
LOG_D(RRC,"[UE %d] State = Attached (eNB %d)\n",ue_mod_idP,eNB_index);
}
} // !EPC_MODE_ENABLED

View File

@@ -79,7 +79,6 @@
#include "LTE_MeasResults.h"
#include "RRC/NAS/nas_config.h"
#include "RRC/NAS/rb_config.h"
#include "rrc_eNB_S1AP.h"
#include "rrc_eNB_GTPV1U.h"
@@ -5144,7 +5143,6 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
{
int drb_id;
int oip_ifup = 0;
int dest_ip_offset = 0;
uint8_t kRRCenc[32] = {0};
uint8_t kRRCint[32] = {0};
uint8_t kUPenc[32] = {0};
@@ -5257,26 +5255,18 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
LOG_I(OIP, "[eNB %d] trying to bring up the OAI interface oai%d\n",
ctxt_pP->module_id,
ctxt_pP->module_id);
oip_ifup = nas_config(ctxt_pP->module_id, // interface index
ctxt_pP->module_id + 1, // third octet
ctxt_pP->module_id + 1, // fourth octet
"oai");
char ip[20];
snprintf(ip, sizeof(ip), "10.0.%d.%d", ctxt_pP->module_id + 1, ctxt_pP->module_id + 1);
oip_ifup = nas_config(ctxt_pP->module_id, AF_INET, ip, "oaitun_oai");
if (oip_ifup == 0) { // interface is up --> send a config the DRB
module_id_t ue_module_id;
dest_ip_offset = 8;
LOG_I(OIP,
"[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n",
ctxt_pP->module_id, ctxt_pP->module_id,
(long int)((ue_context_pP->local_uid * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity));
ue_module_id = 0; // Was oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid];
rb_conf_ipv4(0, //add
ue_module_id, //cx
ctxt_pP->module_id, //inst
(ue_module_id * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity, // RB
0, //dscp
ipv4_address(ctxt_pP->module_id + 1, ctxt_pP->module_id + 1), //saddr
ipv4_address(ctxt_pP->module_id + 1, dest_ip_offset + ue_module_id + 1)); //daddr
AssertFatal(false, "not implemented\n");
LOG_D(RRC, "[eNB %d] State = Attached (UE rnti %x module id %u)\n",
ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ue_module_id);
} /* oip_ifup */

View File

@@ -19,464 +19,114 @@
* contact@openairinterface.org
*/
/*! \file nas_config.c
* \brief Configures the nasmesh interface
* \author Daniel Camara and Navid Nikaein
* \date 2006-2011
* \version 0.1
* \email:navid.nikaein@eurecom.fr
* \company Eurecom
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/route.h>
#include "nas_config.h"
#include "common/utils/LOG/log.h"
#include "executables/lte-softmodem.h"
#include "common/config/config_userapi.h"
#include "pdcp.h"
#include "common/utils/system.h"
//default values according to the examples,
/*
* \brief set a genneric interface parameter
* \param ifn the name of the interface to modify
* \param if_addr the address that needs to be modified
* \param operation one of SIOCSIFADDR (set interface address), SIOCSIFNETMASK
* (set network mask), SIOCSIFBRDADDR (set broadcast address), SIOCSIFFLAGS
* (set flags)
* \return true on success, false otherwise
*/
static bool setInterfaceParameter(int sock_fd, const char *ifn, int af, const char *if_addr, int operation)
{
struct ifreq ifr = {0};
strncpy(ifr.ifr_name, ifn, sizeof(ifr.ifr_name));
char *baseNetAddress ;
char *netMask ;
char *broadcastAddr ;
#define NASHLP_NETPREFIX "<NAS network prefix, two first bytes of network addresses>\n"
#define NASHLP_NETMASK "<NAS network mask>\n"
#define NASHLP_BROADCASTADDR "<NAS network broadcast address>\n"
void nas_getparams(void) {
// this datamodel require this static because we partially keep data like baseNetAddress (malloc on a global)
// but we loose the opther attributes in nasoptions between two calls if is is not static !
// clang-format off
paramdef_t nasoptions[] = {
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* configuration parameters for netlink, includes network parameters when running in noS1 mode */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
{"NetworkPrefix", NASHLP_NETPREFIX, 0, .strptr=&baseNetAddress, .defstrval="10.0", TYPE_STRING, 0 },
{"NetworkMask", NASHLP_NETMASK, 0, .strptr=&netMask, .defstrval="255.255.255.0", TYPE_STRING, 0 },
{"BroadcastAddr", NASHLP_BROADCASTADDR, 0, .strptr=&broadcastAddr, .defstrval="10.0.255.255", TYPE_STRING, 0 },
};
// clang-format on
config_get(config_get_if(), nasoptions, sizeofArray(nasoptions), "nas.noS1");
}
void setBaseNetAddress (char *baseAddr) {
strcpy(baseNetAddress,baseAddr);
}
char *getBaseNetAddress (void) {
return baseNetAddress;
}
void setNetMask (char *baseAddr) {
strcpy(netMask,baseAddr);
}
char *getNetMask (void) {
return netMask;
}
void setBroadcastAddress (char *baseAddr) {
strcpy(broadcastAddr, baseAddr);
}
char *getBroadcastAddress (void) {
return broadcastAddr;
}
//Add Gateway to the interface
int set_gateway(char *interfaceName, char *gateway) {
int sock_fd;
struct rtentry rt;
struct sockaddr_in addr;
if((sock_fd = socket(AF_INET,SOCK_DGRAM,0)) < 0) {
perror("socket failed");
return 1;
}
memset (&rt, 0, sizeof (rt));
addr.sin_family = AF_INET;
/*set Destination addr*/
inet_aton("0.0.0.0",&addr.sin_addr);
memcpy(&rt.rt_dst, &addr, sizeof(struct sockaddr_in));
/*set gateway addr*/
inet_aton(gateway,&addr.sin_addr);
memcpy(&rt.rt_gateway, &addr, sizeof(struct sockaddr_in));
/*set genmask addr*/
inet_aton("0.0.0.0",&addr.sin_addr);
memcpy(&rt.rt_genmask, &addr, sizeof(struct sockaddr_in));
rt.rt_dev = interfaceName;
//rt.rt_flags = RTF_UP|RTF_GATEWAY|RTF_DEFAULT;
/* SR: rt_flags on 16 bits but RTF_DEFAULT = 0x00010000
* therefore doesn't lie in container -> disable it
*/
//rt.rt_flags = RTF_GATEWAY|RTF_DEFAULT;
rt.rt_flags = RTF_GATEWAY;
if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
close(sock_fd);
if(strstr(strerror(errno),"File exists") == NULL) {
LOG_E(OIP,"ioctl SIOCADDRT failed : %s\n",strerror(errno));
return 2;
} else { /*if SIOCADDRT error is route exist, retrun success*/
LOG_I(OIP,"File Exist ...\n");
LOG_I(OIP,"set_gateway OK!\n");
return 0;
}
}
close(sock_fd);
LOG_D(OIP,"Set Gateway OK!\n");
return 0;
}
// sets a genneric interface parameter
// (SIOCSIFADDR, SIOCSIFNETMASK, SIOCSIFBRDADDR, SIOCSIFFLAGS)
int setInterfaceParameter(char *interfaceName, char *settingAddress, int operation) {
int sock_fd;
struct ifreq ifr;
struct sockaddr_in addr;
if((sock_fd = socket(AF_INET,SOCK_DGRAM,0)) < 0) {
LOG_E(OIP,"Setting operation %d, for %s, address, %s : socket failed\n",
operation, interfaceName, settingAddress);
return 1;
}
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, interfaceName, sizeof(ifr.ifr_name)-1);
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
inet_aton(settingAddress,&addr.sin_addr);
DevAssert(af == AF_INET);
struct sockaddr_in addr = {.sin_family = AF_INET};
//struct sockaddr_in6 addr = {.sin_family = AF_INET6};
inet_pton(af, if_addr, &addr.sin_addr);
//inet_pton(af, if_addr, &addr.sin6_addr);
memcpy(&ifr.ifr_ifru.ifru_addr,&addr,sizeof(struct sockaddr_in));
//memcpy(&ifr.ifr_ifru.ifru_addr,&addr,sizeof(struct sockaddr_in6));
if(ioctl(sock_fd,operation,&ifr) < 0) {
close(sock_fd);
LOG_E(OIP,"Setting operation %d, for %s, address, %s : ioctl call failed\n",
operation, interfaceName, settingAddress);
return 2;
}
close(sock_fd);
return 0;
bool success = ioctl(sock_fd,operation,&ifr) == 0;
if (!success)
LOG_E(OIP, "Setting operation %d for %s: ioctl call failed: %d, %s\n", operation, ifn, errno, strerror(errno));
return success;
}
// sets a genneric interface parameter
// (SIOCSIFADDR, SIOCSIFNETMASK, SIOCSIFBRDADDR, SIOCSIFFLAGS)
int bringInterfaceUp(char *interfaceName, int up) {
int sock_fd;
struct ifreq ifr;
/*
* \brief bring interface up (up != 0) or down (up == 0)
*/
typedef enum { INTERFACE_DOWN, INTERFACE_UP } if_action_t;
static bool change_interface_state(int sock_fd, const char *ifn, if_action_t if_action)
{
struct ifreq ifr = {0};
strncpy(ifr.ifr_name, ifn, sizeof(ifr.ifr_name));
if((sock_fd = socket(AF_INET,SOCK_DGRAM,0)) < 0) {
LOG_E(OIP,"Bringing interface UP, for %s, failed creating socket\n", interfaceName);
return 1;
}
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, interfaceName, sizeof(ifr.ifr_name)-1);
if(up) {
if (if_action == INTERFACE_UP) {
ifr.ifr_flags |= IFF_UP | IFF_NOARP | IFF_MULTICAST;
if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t)&ifr) == -1) {
close(sock_fd);
LOG_E(OIP,"Bringing interface UP, for %s, failed UP ioctl\n", interfaceName);
return 2;
}
} else {
// printf("desactivation de %s\n", interfaceName);
ifr.ifr_flags &= (~IFF_UP);
if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t)&ifr) == -1) {
close(sock_fd);
LOG_E(OIP,"Bringing interface down, for %s, failed UP ioctl\n", interfaceName);
return 2;
}
}
// printf("UP/DOWN OK!\n");
close( sock_fd );
return 0;
bool success = ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t)&ifr) == 0;
if (!success) {
const char* action = if_action == INTERFACE_DOWN ? "DOWN" : "UP";
LOG_E(OIP, "Bringing interface %s for %s: ioctl call failed: %d, %s\n", action, ifn, errno, strerror(errno));
}
return success;
}
// non blocking full configuration of the interface (address, net mask, and broadcast mask)
int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress) {
bringInterfaceUp(interfaceName, 0);
// sets the machine address
int returnValue= setInterfaceParameter(interfaceName, ipAddress,SIOCSIFADDR);
// sets the machine network mask
if(!returnValue)
returnValue= setInterfaceParameter(interfaceName, networkMask,SIOCSIFNETMASK);
// sets the machine broadcast address
if(!returnValue)
returnValue= setInterfaceParameter(interfaceName, broadcastAddress,SIOCSIFBRDADDR);
// if(!returnValue)
// returnValue=set_gateway(interfaceName, broadcastAddress);
if(!returnValue)
returnValue = bringInterfaceUp(interfaceName, 1);
return returnValue;
}
int nas_config_mbms(int interface_id, int thirdOctet, int fourthOctet, char *ifname) {
//char buf[5];
char ipAddress[20];
char broadcastAddress[20];
char interfaceName[20];
int returnValue;
//if(strcmp(ifname,"ue") == 0)
//sprintf(ipAddress, "%s.%d.%d", "20.0",thirdOctet,fourthOctet);
////else
sprintf(ipAddress, "%s.%d.%d",baseNetAddress,thirdOctet,fourthOctet);
sprintf(broadcastAddress, "%s.%d.255",baseNetAddress, thirdOctet);
sprintf(interfaceName, "%s%s%d", (UE_NAS_USE_TUN || ENB_NAS_USE_TUN)?"oaitun_":ifname,
UE_NAS_USE_TUN?ifname/*"ue"*/: (ENB_NAS_USE_TUN?ifname/*"enb"*/:""),interface_id);
bringInterfaceUp(interfaceName, 0);
// sets the machine address
returnValue= setInterfaceParameter(interfaceName, ipAddress,SIOCSIFADDR);
// sets the machine network mask
if(!returnValue)
returnValue= setInterfaceParameter(interfaceName, netMask,SIOCSIFNETMASK);
// sets the machine broadcast address
if(!returnValue)
returnValue= setInterfaceParameter(interfaceName, broadcastAddress,SIOCSIFBRDADDR);
if(!returnValue)
bringInterfaceUp(interfaceName, 1);
if(!returnValue)
LOG_I(OIP,"Interface %s successfully configured, ip address %s, mask %s broadcast address %s\n",
interfaceName, ipAddress, netMask, broadcastAddress);
else
LOG_E(OIP,"Interface %s couldn't be configured (ip address %s, mask %s broadcast address %s)\n",
interfaceName, ipAddress, netMask, broadcastAddress);
return returnValue;
}
int nas_config_mbms_s1(int interface_id, int thirdOctet, int fourthOctet, char *ifname) {
//char buf[5];
char ipAddress[20];
char broadcastAddress[20];
char interfaceName[20];
int returnValue;
//if(strcmp(ifname,"ue") == 0)
//sprintf(ipAddress, "%s.%d.%d", "20.0",thirdOctet,fourthOctet);
////else
sprintf(ipAddress, "%s.%d.%d","10.0",thirdOctet,fourthOctet);
sprintf(broadcastAddress, "%s.%d.255","10.0", thirdOctet);
sprintf(interfaceName, "%s%s%d", "oaitun_",ifname,interface_id);
bringInterfaceUp(interfaceName, 0);
// sets the machine address
returnValue= setInterfaceParameter(interfaceName, ipAddress,SIOCSIFADDR);
// sets the machine network mask
if(!returnValue)
returnValue= setInterfaceParameter(interfaceName, "255.255.255.0",SIOCSIFNETMASK);
printf("returnValue %d\n",returnValue);
// sets the machine broadcast address
if(!returnValue)
returnValue= setInterfaceParameter(interfaceName, broadcastAddress,SIOCSIFBRDADDR);
printf("returnValue %d\n",returnValue);
if(!returnValue)
bringInterfaceUp(interfaceName, 1);
printf("returnValue %d\n",returnValue);
if(!returnValue)
LOG_I(OIP,"Interface %s successfully configured, ip address %s, mask %s broadcast address %s\n",
interfaceName, ipAddress, "255.255.255.0", broadcastAddress);
else
LOG_E(OIP,"Interface %s couldn't be configured (ip address %s, mask %s broadcast address %s)\n",
interfaceName, ipAddress, "255.255.255.0", broadcastAddress);
return returnValue;
}
// non blocking full configuration of the interface (address, and the two lest octets of the address)
int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifname) {
//char buf[5];
char ipAddress[20];
char broadcastAddress[20];
char interfaceName[20];
int returnValue;
sprintf(ipAddress, "%s.%d.%d", baseNetAddress,thirdOctet,fourthOctet);
sprintf(broadcastAddress, "%s.%d.255",baseNetAddress, thirdOctet);
sprintf(interfaceName, "%s%s%d", (UE_NAS_USE_TUN || ENB_NAS_USE_TUN)?"oaitun_":ifname,
UE_NAS_USE_TUN?"ue": (ENB_NAS_USE_TUN?"enb":""),interface_id);
bringInterfaceUp(interfaceName, 0);
// sets the machine address
returnValue= setInterfaceParameter(interfaceName, ipAddress,SIOCSIFADDR);
// sets the machine network mask
if(!returnValue)
returnValue= setInterfaceParameter(interfaceName, netMask,SIOCSIFNETMASK);
// sets the machine broadcast address
if(!returnValue)
returnValue= setInterfaceParameter(interfaceName, broadcastAddress,SIOCSIFBRDADDR);
if(!returnValue)
returnValue=bringInterfaceUp(interfaceName, 1);
if(!returnValue)
LOG_I(OIP,"Interface %s successfully configured, ip address %s, mask %s broadcast address %s\n",
interfaceName, ipAddress, netMask, broadcastAddress);
else
LOG_E(OIP,"Interface %s couldn't be configured (ip address %s, mask %s broadcast address %s)\n",
interfaceName, ipAddress, netMask, broadcastAddress);
int res;
char command_line[500];
res = sprintf(command_line,
"ip rule add from %s/32 table %d && "
"ip rule add to %s/32 table %d && "
"ip route add default dev %s%d table %d",
ipAddress, interface_id - 1 + 10000,
ipAddress, interface_id - 1 + 10000,
UE_NAS_USE_TUN ? "oaitun_ue" : "oip",
interface_id, interface_id - 1 + 10000);
if (res < 0) {
LOG_E(OIP,"Could not create ip rule/route commands string\n");
return res;
}
background_system(command_line);
return returnValue;
}
// Blocking full configuration of the interface (address, net mask, and broadcast mask)
int blocking_NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress) {
char command[200];
command[0]='\0';
strcat(command, "ifconfig ");
strncat(command, interfaceName, sizeof(command) - strlen(command) - 1);
strncat(command, " ", sizeof(command) - strlen(command) - 1);
strncat(command, ipAddress, sizeof(command) - strlen(command) - 1);
strncat(command, " networkMask ", sizeof(command) - strlen(command) - 1);
strncat(command, networkMask, sizeof(command) - strlen(command) - 1);
strncat(command, " broadcast ", sizeof(command) - strlen(command) - 1);
strncat(command, broadcastAddress, sizeof(command) - strlen(command) - 1);
// ifconfig nasmesh0 10.0.1.1 networkMask 255.255.255.0 broadcast 10.0.1.255
int i = system (command);
return i;
}
// program help
void helpOptions(char **argv) {
printf("Help for %s\n", argv[0]);
printf(" -i <interfaceName>\n");
printf(" -a <IP address>\n");
printf(" -n <Net mask>\n");
printf(" -b <broadcast address>\n");
printf(" -h Shows this help\n");
printf("If no option is passed as parameter the default values are: \n");
printf(" Interface Name: nasmesh0\n");
printf(" IP Address: 10.0.1.1\n");
printf(" Net mask: 255.255.255.0\n");
printf(" Broadcast address: [Beginning of the IP address].255\n");
exit(1);
}
// creates the broadcast address if it wasn't set before
void createBroadcast(char *broadcastAddress) {
int pos=strlen(broadcastAddress)-1;
while(broadcastAddress[pos]!='.')
pos--;
broadcastAddress[++pos]='2';
broadcastAddress[++pos]='2';
broadcastAddress[++pos]='5';
broadcastAddress[++pos]='\0';
}
#ifdef STANDALONE
// main function
//---------------------------------------------------------------------------
int main(int argc,char **argv)
//---------------------------------------------------------------------------
bool nas_config(int interface_id, int af, const char *ip, const char *ifpref)
{
int c;
char interfaceName[100];
char ipAddress[100];
char networkMask[100];
char broadcastAddress[100];
strcpy(interfaceName, "oai0");
strcpy(ipAddress, "10.0.1.1");
strcpy(networkMask, "255.255.255.0");
broadcastAddress[0]='\0';
char interfaceName[IFNAMSIZ];
snprintf(interfaceName, sizeof(interfaceName), "%s%d", ifpref, interface_id);
while ((c = getopt (argc, argv, "i:a:n:b:h")) != -1)
switch (c) {
case 'h':
helpOptions(argv);
break;
case 'i':
strcpy(interfaceName,optarg);
break;
case 'a':
strcpy(ipAddress,optarg);
break;
case 'n':
strcpy(networkMask,optarg);
break;
case 'b':
strcpy(broadcastAddress,optarg);
break;
case '?':
if (isprint (optopt))
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf (stderr,
"Unknown option character `\\x%x'.\n",
optopt);
return 1;
default:
abort ();
}
if(strlen(broadcastAddress)==0) {
strcpy(broadcastAddress,ipAddress);
createBroadcast(broadcastAddress);
int sock_fd = socket(af, SOCK_DGRAM, 0);
if (sock_fd < 0) {
LOG_E(UTIL, "Failed creating socket for interface management: %d, %s\n", errno, strerror(errno));
return false;
}
printf("Command: ifconfig %s %s networkMask %s broadcast %s\n", interfaceName, ipAddress, networkMask, broadcastAddress);
NAS_config(interfaceName, ipAddress, networkMask, broadcastAddress);
//test
// setBaseNetAddress("11.11");
// nas_config(interfaceName, 33, 44);
}
change_interface_state(sock_fd, interfaceName, INTERFACE_DOWN);
bool success = setInterfaceParameter(sock_fd, interfaceName, af, ip, SIOCSIFADDR);
#endif
if (success)
success = change_interface_state(sock_fd, interfaceName, INTERFACE_UP);
if (success)
LOG_I(OIP, "Interface %s successfully configured, ip address %s\n", interfaceName, ip);
else
LOG_E(OIP, "Interface %s couldn't be configured (ip address %s)\n", interfaceName, ip);
close(sock_fd);
if (success) {
int table_id = interface_id - 1 + 10000;
char command_line[500];
int res = sprintf(command_line,
"ip rule add from %s/32 table %d && "
"ip rule add to %s/32 table %d && "
"ip route add default dev %s table %d",
ip,
table_id,
ip,
table_id,
interfaceName,
table_id);
if (res < 0) {
LOG_E(OIP, "Could not create ip rule/route commands string\n");
return res;
}
background_system(command_line);
}
return success;
}

View File

@@ -19,166 +19,27 @@
* contact@openairinterface.org
*/
/*! \file nas_config.h
* \brief Configures the nasmesh interface
* \author Daniel Camara and navid nikaein
* \date 2006-2011
* \version 0.1
* \company Eurecom
*/
#ifndef NAS_CONFIG_H_
#define NAS_CONFIG_H_
#include <netinet/in.h>
/*! \fn void void nas_getparams(void)(void)
* \brief This function get parameters used to configure network interface when running in noS1 mode
* \note
* @ingroup _nas
*/
void nas_getparams(void);
/*! \fn int NAS_config(char*, char*, char*, char*)
* \brief This function initializes the nasmesh interface
* \param[in] interfaceName, the name of the interface, e.g. nasmesh0 or nasmesh1
* \param[in] ipAddress, the address of the interface, e.g. 10.0.1.1
* \param[in] networkMask, the network mask to be used, e.g. 255.255.255.0
* \param[in] broadcastAddress, the broadcast address for the subnet, e.g. 10.0.1.255
* \return 0 on success, otherwise 1, if couldn't open a socket and 2 if the ioctl fails
* \note
* @ingroup _nas
*/
int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress);
#include <stdbool.h>
//#include <netinet/in.h>
#include <arpa/inet.h> // for AF_INET and AF_INET6
/*! \fn int nas_config(char*, int, int)
* \brief This function initializes the nasmesh interface using the basic values,
* basic address, network mask and broadcast address, as the default configured
* ones
* \param[in] interfaceName, the name of the interface, e.g. nasmesh0 or nasmesh1
* \param[in] third octet of the ip address e.g. for the 10.1.2.3 address would be 2
* \param[in] fourth octet of the ip address e.g. for the 10.1.2.3 address would be 3
* \return 0 on success, otherwise 1, if couldn't open a socket and 2 if the ioctl fails
* \param[in] interface_id number of this interface, prepended after interface
* name
* \param[in] af AF_INET or AF_INET6
* \param[in] ip IPv4 address of this interface as a string
* \param[in] ifprefix interface name prefix to which an interface number will
* be appended
* \return true on success, otherwise false
* \note
* @ingroup _nas
*/
int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifsuffix);
bool nas_config(int interface_id, int af, const char *ip, const char *ifprefix);
/*! \fn int nas_config_mbms(char*, int, int)
* \brief This function initializes the nasmesh interface using the basic values,
* basic address, network mask and broadcast address, as the default configured
* ones
* \param[in] interfaceName, the name of the interface, e.g. nasmesh0 or nasmesh1
* \param[in] third octet of the ip address e.g. for the 10.1.2.3 address would be 2
* \param[in] fourth octet of the ip address e.g. for the 10.1.2.3 address would be 3
* \return 0 on success, otherwise 1, if couldn't open a socket and 2 if the ioctl fails
* \note
* @ingroup _nas
*/
int nas_config_mbms(int interface_id, int thirdOctet, int fourthOctet, char *ifsuffix);
/*! \fn int nas_config_mbms_s1(char*, int, int)
* \brief This function initializes the nasmesh interface using the basic values,
* basic address, network mask and broadcast address, as the default configured
* ones
* \param[in] interfaceName, the name of the interface, e.g. nasmesh0 or nasmesh1
* \param[in] third octet of the ip address e.g. for the 10.1.2.3 address would be 2
* \param[in] fourth octet of the ip address e.g. for the 10.1.2.3 address would be 3
* \return 0 on success, otherwise 1, if couldn't open a socket and 2 if the ioctl fails
* \note
* @ingroup _nas
*/
int nas_config_mbms_s1(int interface_id, int thirdOctet, int fourthOctet, char *ifsuffix);
/*! \fn int blocking_NAS_config(char*, char*, char*, char*)
* \brief This function initializes the nasmesh interface, in a blocking way,
* the system calls are interrupted
* \param[in] interfaceName, the name of the interface, e.g. nasmesh0 or nasmesh1
* \param[in] ipAddress, the address of the interface, e.g. 10.0.1.1
* \param[in] networkMask, the network mask to be used, e.g. 255.255.255.0
* \param[in] broadcastAddress, the broadcast address for the subnet, e.g. 10.0.1.255
* \return 0 on success, otherwise 1
* \note
* @ingroup _nas
*/
int blocking_NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress);
/*! \fn int setInterfaceParameter(char*, char*, int)
* \brief This function sets an genneric interface parameter (SIOCSIFADDR,
* SIOCSIFNETMASK, SIOCSIFBRDADDR, SIOCSIFFLAGS)
* \param[in] interfaceName, the name of the interface, e.g. nasmesh0 or nasmesh1
* \param[in] address, the value of the parameter to set, e.g. 10.0.1.255
* \param[in] operation, the operation to perform, (SIOCSIFADDR, SIOCSIFNETMASK,
* SIOCSIFBRDADDR, SIOCSIFFLAGS), e.g. SIOCSIFBRDADDR
* \return 0 on success, otherwise 1, if couldn't open a socket and 2 if the ioctl fails
* \note
* @ingroup _nas
*/
int setInterfaceParameter(char *interfaceName, char *settingAddress, int operation);
/*! \fn int set_gateway(char*, char*)
* \brief This function sets the interface gateway
* \param[in] interfaceName, the name of the interface, e.g. nasmesh0 or nasmesh1
* \param[in] address, the address of the gateway, e.g. 10.0.1.2
* \return 0 on success, otherwise 1, if couldn't open a socket and 2 if the ioctl fails
* \note
* @ingroup _nas
*/
int set_gateway(char *interfaceName, char *gateway);
/*! \fn void setBaseNetAddress(char*)
* \brief This function sets the basic network address used
* \param[in] baseAddr, the new basic address e.g.for 10.0.1.2, would be 10.0
* \note
* @ingroup _nas
*/
void setBaseNetAddress(char *baseAddr);
/*! \fn char* getBaseNetAddress()
* \brief This function returns the basic network address used
* \return the basic network address in use
* \note
* @ingroup _nas
*/
char *getBaseNetAddress(void);
/*! \fn void setNetMask(char*)
* \brief This function sets the new default network mask used
* \param[in] newNetworkMask, the new network mask e.g.for 255.255.0.0
* \note
* @ingroup _nas
*/
void setNetMask(char *baseAddr);
/*! \fn char* getNetMask()
* \brief This function returns the network mask address in use
* \return the network mask in use
* \note
* @ingroup _nas
*/
char *getNetMask(void);
/*! \fn coid setBroadcastAddress(char*)
* \brief This function sets the new broadcast address used
* \param[in] newNetworkMask, the new broadcast address e.g.for 10.0.255.255
* \note
* @ingroup _nas
*/
void setBroadcastAddress(char *baseAddr);
/*! \fn char* getBroadcastAddress()
* \brief This function returns the broadcast address in use
* \return the broadcast address in use
* \note
* @ingroup _nas
*/
char *getBroadcastAddress(void);
int bringInterfaceUp(char *interfaceName, int up);
int rb_validate_config_ipv4(int cx, int inst, int rb);
int rb_conf_ipv4(int action, int cx, int inst, int rb, int dscp, in_addr_t saddr_ipv4, in_addr_t daddr_ipv4);
void rb_ioctl_init(int inst);
int rb_stats_req(int inst);
void init_socket(void);
in_addr_t ipv4_address(int thirdOctet, int fourthOctet);
#endif /*NAS_CONFIG_H_*/

View File

@@ -1,280 +0,0 @@
/*
* 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
*/
/*! \file rb_config.c
* \brief User-space utility for configuring NASMESH IOCTL interface
* \author Raymond Knopp and Navid Nikaein
* \date 2009
* \version 1.1
* \warning
* @ingroup driver
*/
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include "nas_config.h"
#include "common/utils/LOG/log.h"
#include "NETWORK_DRIVER/MESH/rrc_nas_primitives.h"
#include "NETWORK_DRIVER/MESH/ioctl.h"
#include "NETWORK_DRIVER/MESH/constant.h"
#define BUF_SIZE 800
// Global variables
//int sd_graal;
//int fd; // moved to the struct rb_config
//char myIPAddr[16]; // local IP Address
//int meas_counter;
//struct ralu_priv ru_priv;
//struct ralu_priv *ralupriv;
//ioctl
char dummy_buffer[BUF_SIZE]; // moved to stats req
struct nas_ioctl gifr;
//int wait_start_nas;
static int fd;
static int socket_enabled;
void init_socket(void)
{
if ((fd=socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
LOG_E(OIP,"ERROR opening socket\n");
socket_enabled=0;
}
socket_enabled=1;
}
void rb_ioctl_init(int inst)
{
/* init the gifr struct for the given inst */
sprintf(gifr.name, "oai%d",inst);
memset ((void *)dummy_buffer,0,BUF_SIZE);
gifr.msg= &(dummy_buffer[0]);
}
int rb_validate_config_ipv4(int cx, int inst, int rb)
{
if (inst == -1) {
LOG_E(OIP,"Specify an interface\n");
return(1);
}
if (rb == -1) {
LOG_E(OIP,"Specify an RAB identifier \n");
return (1);
}
if (cx == -1) {
LOG_E(OIP,"Specify an LCR \n");
return(1);
}
/*
if ( inet_aton(src,&saddr_ipv4)<= 0) {
LOG_E(OIP,"Specify a source IP address\n");
return(1);
}
if (inet_aton(src,&saddr_ipv4)<= 0 0) {
LOG_E(OIP,"Specify a destination IP address\n");
return(1);
}
*/
return (0);
}
int rb_conf_ipv4(int action,int cx, int inst, int rb, int dscp, in_addr_t saddr_ipv4, in_addr_t daddr_ipv4)
{
//int rb_conf_ipv6(int action,int cx, int inst, int qos, in6_addr src, in6_addr dst) {
//int rb_conf(rb_config *rb_cfg) {
int err;
struct nas_msg_rb_establishment_request *msgreq;
struct nas_msg_class_add_request *msgreq_class;
struct nas_msg_rb_release_request *msgrel;
struct nas_msg_class_del_request *msgdel_class;
if (socket_enabled ==0) {
init_socket();
}
rb_ioctl_init(inst);
if (rb_validate_config_ipv4(cx,inst,rb) > 0) {
LOG_E(OIP, "OIP configuration failed, inputs parameters incorrect\n");
return (1);
}
// add an OIP
if (action == 0 ) {
msgreq = (struct nas_msg_rb_establishment_request *)(gifr.msg);
msgreq->rab_id = (nasRadioBearerId_t) rb;
msgreq->lcr = (nasRadioBearerId_t) cx;
msgreq->qos = 0;
gifr.type = NAS_MSG_RB_ESTABLISHMENT_REQUEST;
if ((err=ioctl(fd, NAS_IOCTL_RRM, &gifr)) < 0) {
perror("IOCTL error: OIP ESTAB REQ\n");
LOG_E(OIP,"IOCTL error: OIP ESTAB REQ");
}
msgreq_class = (struct nas_msg_class_add_request *)(gifr.msg);
msgreq_class->rab_id = (nasRadioBearerId_t) rb;
msgreq_class->lcr = (nasRadioBearerId_t) cx;
msgreq_class->version = 4;//ipv4
msgreq_class->classref = 0 + (msgreq_class->lcr<<3);
msgreq_class->dir = NAS_DIRECTION_SEND;
msgreq_class->fct = NAS_FCT_QOS_SEND;
msgreq_class->saddr.ipv4 = saddr_ipv4;
msgreq_class->daddr.ipv4 = daddr_ipv4;
// TO BE FIXED WHEN WE CAN SPECIFY A PROTOCOL-based rule
msgreq_class->protocol = NAS_PROTOCOL_DEFAULT;
msgreq_class->dscp=dscp;
gifr.type = NAS_MSG_CLASS_ADD_REQUEST;
if ((err=ioctl(fd, NAS_IOCTL_RRM, &gifr)) < 0 ) {
perror("IOCTL error: DIR SEND: ADD REQ");
LOG_E(OIP,"IOCTL error: DIR SEND: ADD REQ\n");
}
msgreq_class->rab_id = (nasRadioBearerId_t)rb;
msgreq_class->lcr = (nasRadioBearerId_t)cx;
msgreq_class->classref = 1+(msgreq_class->lcr<<3);
msgreq_class->dir = NAS_DIRECTION_RECEIVE;
msgreq_class->daddr.ipv4 = saddr_ipv4;
msgreq_class->saddr.ipv4 = daddr_ipv4;
gifr.type = NAS_MSG_CLASS_ADD_REQUEST;
if ((err=ioctl(fd, NAS_IOCTL_RRM, &gifr)) < 0 ) {
perror("IOCTL error: DIR RECEIVE: ADD REQ");
LOG_E(OIP,"IOCTL error: DIR RECEIVE: ADD REQ\n");
}
}
// OIP DEL
else if (action == 1) {
msgrel = (struct nas_msg_rb_release_request *)(gifr.msg);
msgrel->rab_id = rb;
msgrel->lcr = cx;
gifr.type = NAS_MSG_RB_RELEASE_REQUEST;
if ((err=ioctl(fd, NAS_IOCTL_RRM, &gifr)) < 0) {
perror("IOCTL error: OIP RELEASE REQ");
LOG_E(OIP,"IOCTL error: OIP RELEASE REQ\n");
}
msgdel_class = (struct nas_msg_class_del_request *)(gifr.msg);
msgdel_class->lcr = cx;
msgdel_class->dir = NAS_DIRECTION_SEND;
msgdel_class->classref = 0 + (msgdel_class->lcr<<3);
msgdel_class->dscp=dscp;
gifr.type = NAS_MSG_CLASS_DEL_REQUEST;
if ((err=ioctl(fd, NAS_IOCTL_RRM, &gifr)) < 0 ) {
perror("IOCTL error: DIR SEND : CLASS DEL REQ");
LOG_E(OIP,"IOCTL error: DIR SEND : CLASS DEL REQ\n");
}
msgdel_class->lcr = cx;
msgdel_class->classref = 1+(msgdel_class->lcr<<3);
msgdel_class->dir = NAS_DIRECTION_RECEIVE;
gifr.type = NAS_MSG_CLASS_DEL_REQUEST;
if ((err=ioctl(fd, NAS_IOCTL_RRM, &gifr)) < 0 ) {
perror("IOCTL error: DIR RECEIVE : CLASS DEL REQ");
LOG_E(OIP,"IOCTL erro: DIR RECEIVE : CLASS DEL REQ\n");
}
}
return(0);
}
int rb_stats_req(int inst)
{
if ( fd <= 0 ) {
return (1);
} /* request stats without defining the interface */
else if (inst == -1) {
// printf("Specify an interface for statistics request \n");
LOG_E(OIP,"Specify an interface for statistics request \n");
return (1);
}
struct nas_msg_statistic_reply *msgrep;
int err;
rb_ioctl_init(inst);
gifr.type = NAS_MSG_STATISTIC_REQUEST;
msgrep=(struct nas_msg_statistic_reply *)(gifr.msg);
if ((err = ioctl(fd, NAS_IOCTL_RRM, &gifr)) < 0 ) {
perror("IOCTL error: STATS REQ FAILED\n");
LOG_E(OIP,"IOCTL error: STATS REQ FAILED\n");
}
LOG_I(OIP,"ioctl :Statistics request");
LOG_I(OIP,"tx_packets = %u, rx_packets = %u\n", msgrep->tx_packets, msgrep->rx_packets);
LOG_I(OIP,"tx_bytes = %u, rx_bytes = %u\n", msgrep->tx_bytes, msgrep->rx_bytes);
LOG_I(OIP,"tx_errors = %u, rx_errors = %u\n", msgrep->tx_errors, msgrep->rx_errors);
LOG_I(OIP,"tx_dropped = %u, rx_dropped = %u\n", msgrep->tx_dropped, msgrep->rx_dropped);
return (0);
}
in_addr_t ipv4_address (int thirdOctet, int fourthOctet)
{
struct in_addr saddr_ipv4;
char ipAddress[20];
sprintf(ipAddress, "10.0.%d.%d",thirdOctet,fourthOctet);
inet_aton(ipAddress,&saddr_ipv4);
return saddr_ipv4.s_addr;
}

View File

@@ -1,69 +0,0 @@
/*
* 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
*/
/** \file rb_config.h
* \brief Openair radio bearer configuration header file
* \author Raymond Knopp and Navid Nikaein
*/
#ifndef __RB_CONFIG_H__
#define __RB_CONFIG_H__
#include <netinet/in.h>
/*
typedef struct {
int fd; // socket file descriptor
int stats;
int action; // add or delete
int rb;
int cx;
int inst;
int saddr_ipv4set;
int daddr_ipv4set;
in_addr_t saddr_ipv4;
in_addr_t daddr_ipv4;
int saddr_ipv6set;
int daddr_ipv6set;
struct in6_addr saddr_ipv6;
struct in6_addr daddr_ipv6;
int dscp;
} rb_config;
*/
int rb_validate_config_ipv4(int cx, int inst, int rb);
int rb_conf_ipv4(int action,int cx, int inst, int rb, int dscp, in_addr_t saddr_ipv4, in_addr_t daddr_ipv4);
void rb_ioctl_init(int inst);
int rb_stats_req(int inst);
void init_socket(void);
in_addr_t ipv4_address (int thirdOctet, int fourthOctet);
#endif

View File

@@ -74,7 +74,6 @@
#include "T.h"
#include "RRC/NAS/nas_config.h"
#include "RRC/NAS/rb_config.h"
#include "openair3/SECU/secu_defs.h"

View File

@@ -66,7 +66,6 @@
#endif
#include "RRC/NAS/nas_config.h"
#include "RRC/NAS/rb_config.h"
#include "SIMULATION/TOOLS/sim.h" // for taus
#include "nr_nas_msg_sim.h"

View File

@@ -25,8 +25,6 @@
#include "openair2/RRC/NAS/nas_config.h"
#include "openair2/SDAP/nr_sdap/nr_sdap.h"
extern char *baseNetAddress;
static uint16_t getShort(uint8_t *input)
{
uint16_t tmp16;
@@ -105,19 +103,23 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_
psea_msg.pdu_addr_ie.pdu_length = *curPtr++;
psea_msg.pdu_addr_ie.pdu_type = *curPtr++;
DevAssert(psea_msg.pdu_addr_ie.pdu_type == PDU_SESSION_TYPE_IPV4);
if (psea_msg.pdu_addr_ie.pdu_type == PDU_SESSION_TYPE_IPV4) {
psea_msg.pdu_addr_ie.pdu_addr_oct1 = *curPtr++;
psea_msg.pdu_addr_ie.pdu_addr_oct2 = *curPtr++;
psea_msg.pdu_addr_ie.pdu_addr_oct3 = *curPtr++;
psea_msg.pdu_addr_ie.pdu_addr_oct4 = *curPtr++;
nas_getparams();
sprintf(baseNetAddress, "%d.%d", psea_msg.pdu_addr_ie.pdu_addr_oct1, psea_msg.pdu_addr_ie.pdu_addr_oct2);
nas_config(1, psea_msg.pdu_addr_ie.pdu_addr_oct3, psea_msg.pdu_addr_ie.pdu_addr_oct4, "oaitun_ue");
LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received UE IP: %d.%d.%d.%d\n",
psea_msg.pdu_addr_ie.pdu_addr_oct1,
psea_msg.pdu_addr_ie.pdu_addr_oct2,
psea_msg.pdu_addr_ie.pdu_addr_oct3,
psea_msg.pdu_addr_ie.pdu_addr_oct4);
pdu_address_t *addr = &psea_msg.pdu_addr_ie;
addr->pdu_addr_oct1 = *curPtr++;
addr->pdu_addr_oct2 = *curPtr++;
addr->pdu_addr_oct3 = *curPtr++;
addr->pdu_addr_oct4 = *curPtr++;
char ip[20];
snprintf(ip,
sizeof(ip),
"%d.%d.%d.%d",
addr->pdu_addr_oct1,
addr->pdu_addr_oct2,
addr->pdu_addr_oct3,
addr->pdu_addr_oct4);
nas_config(1, AF_INET, ip, "oaitun_ue");
LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received UE IP: %s\n", ip);
} else {
curPtr += psea_msg.pdu_addr_ie.pdu_length;
}

View File

@@ -53,7 +53,6 @@
#include "openair3/SECU/nas_stream_eia2.h"
#include "openair3/UTILS/conversions.h"
extern char *baseNetAddress;
extern uint16_t NB_UE_INST;
static nr_ue_nas_t nr_ue_nas = {0};
static nr_nas_msg_snssai_t nas_allowed_nssai[8];
@@ -842,11 +841,11 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
void decodeDownlinkNASTransport(as_nas_info_t *initialNasMsg, uint8_t * pdu_buffer){
uint8_t msg_type = *(pdu_buffer + 16);
if(msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC){
sprintf(baseNetAddress, "%d.%d", *(pdu_buffer + 39),*(pdu_buffer + 40));
int third_octet = *(pdu_buffer + 41);
int fourth_octet = *(pdu_buffer + 42);
uint8_t *ip_p = pdu_buffer + 39;
char ip[20];
sprintf(ip, "%d.%d.%d.%d", *(ip_p), *(ip_p + 1), *(ip_p + 2), *(ip_p + 3));
LOG_A(NAS, "Received PDU Session Establishment Accept\n");
nas_config(1,third_octet,fourth_octet,"ue");
nas_config(1, AF_INET, ip, "oaitun_ue");
} else {
LOG_E(NAS, "Received unexpected message in DLinformationTransfer %d\n", msg_type);
}
@@ -1176,7 +1175,7 @@ static void request_default_pdusession(int instance, int nssai_idx)
{
MessageDef *message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_PDU_SESSION_REQ);
NAS_PDU_SESSION_REQ(message_p).pdusession_id = 10; /* first or default pdu session */
NAS_PDU_SESSION_REQ(message_p).pdusession_type = 0x91;
NAS_PDU_SESSION_REQ(message_p).pdusession_type = 0x91; // 0x91 = IPv4, 0x92 = IPv6, 0x93 = IPv4v6
NAS_PDU_SESSION_REQ(message_p).sst = nas_allowed_nssai[nssai_idx].sst;
NAS_PDU_SESSION_REQ(message_p).sd = nas_allowed_nssai[nssai_idx].sd;
itti_send_msg_to_task(TASK_NAS_NRUE, instance, message_p);
@@ -1428,17 +1427,11 @@ void *nas_nrue(void *args_p)
while (offset < payload_container_length) {
if (*(payload_container + offset) == 0x29) { // PDU address IEI
if ((*(payload_container + offset + 1) == 0x05) && (*(payload_container + offset + 2) == 0x01)) { // IPV4
nas_getparams();
sprintf(baseNetAddress, "%d.%d", *(payload_container + offset + 3), *(payload_container + offset + 4));
int third_octet = *(payload_container + offset + 5);
int fourth_octet = *(payload_container + offset + 6);
LOG_I(NAS,
"Received PDU Session Establishment Accept, UE IP: %d.%d.%d.%d\n",
*(payload_container + offset + 3),
*(payload_container + offset + 4),
*(payload_container + offset + 5),
*(payload_container + offset + 6));
nas_config(1, third_octet, fourth_octet, "oaitun_ue");
uint8_t *ip_p = payload_container + offset + 3;
char ip[20];
snprintf(ip, sizeof(ip), "%d.%d.%d.%d", *(ip_p), *(ip_p + 1), *(ip_p + 2), *(ip_p + 3));
LOG_I(NAS, "Received PDU Session Establishment Accept, UE IP: %s\n", ip);
nas_config(1, AF_INET, ip, "oaitun_ue");
break;
}
}

View File

@@ -1,22 +0,0 @@
SUBDIRS = . HASHTABLE
AM_CFLAGS = @ADD_CFLAGS@ \
-I$(top_srcdir)/COMMON \
-I$(top_srcdir)/NAS/EURECOM-NAS/src/api/network \
-I$(top_srcdir)/NAS/EURECOM-NAS/src/include \
-I$(top_srcdir)/SGW-LITE \
-I$(top_srcdir)/INTERTASK_INTERFACE
AM_YFLAGS = -d
noinst_LTLIBRARIES = libutils.la
libutils_la_LDFLAGS = -all-static
libutils_la_SOURCES = \
conversions.h conversions.c \
enum_string.h enum_string.c \
log.c log.h \
mme_config.c mme_config.h \
mcc_mnc_itu.c mcc_mnc_itu.h \
mme_default_values.h \
queue.h tree.h

View File

@@ -1,178 +0,0 @@
/*
* 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
*/
#ifndef __UTILS_MME_CONFIG__H__
#define __UTILS_MME_CONFIG__H__
#include <pthread.h>
#include <stdint.h>
#include "mme_default_values.h"
#define MME_CONFIG_STRING_MME_CONFIG "MME"
#define MME_CONFIG_STRING_REALM "REALM"
#define MME_CONFIG_STRING_MAXENB "MAXENB"
#define MME_CONFIG_STRING_MAXUE "MAXUE"
#define MME_CONFIG_STRING_RELATIVE_CAPACITY "RELATIVE_CAPACITY"
#define MME_CONFIG_STRING_STATISTIC_TIMER "MME_STATISTIC_TIMER"
#define MME_CONFIG_STRING_EMERGENCY_ATTACH_SUPPORTED "EMERGENCY_ATTACH_SUPPORTED"
#define MME_CONFIG_STRING_UNAUTHENTICATED_IMSI_SUPPORTED "UNAUTHENTICATED_IMSI_SUPPORTED"
#define MME_CONFIG_STRING_INTERTASK_INTERFACE_CONFIG "INTERTASK_INTERFACE"
#define MME_CONFIG_STRING_INTERTASK_INTERFACE_QUEUE_SIZE "ITTI_QUEUE_SIZE"
#define MME_CONFIG_STRING_SCTP_CONFIG "SCTP"
#define MME_CONFIG_STRING_SCTP_INSTREAMS "SCTP_INSTREAMS"
#define MME_CONFIG_STRING_SCTP_OUTSTREAMS "SCTP_OUTSTREAMS"
#define MME_CONFIG_STRING_S1AP_CONFIG "S1AP"
#define MME_CONFIG_STRING_S1AP_OUTCOME_TIMER "S1AP_OUTCOME_TIMER"
#define MME_CONFIG_STRING_S1AP_PORT "S1AP_PORT"
#define MME_CONFIG_STRING_GUMMEI_CONFIG "GUMMEI"
#define MME_CONFIG_STRING_MME_CODE "MME_CODE"
#define MME_CONFIG_STRING_MME_GID "MME_GID"
#define MME_CONFIG_STRING_TAI_LIST "TAI_LIST"
#define MME_CONFIG_STRING_MCC "MCC"
#define MME_CONFIG_STRING_MNC "MNC"
#define MME_CONFIG_STRING_TAC "TAC"
#define MME_CONFIG_STRING_NETWORK_INTERFACES_CONFIG "NETWORK_INTERFACES"
#define MME_CONFIG_STRING_INTERFACE_NAME_FOR_S1_MME "MME_INTERFACE_NAME_FOR_S1_MME"
#define MME_CONFIG_STRING_IPV4_ADDRESS_FOR_S1_MME "MME_IPV4_ADDRESS_FOR_S1_MME"
#define MME_CONFIG_STRING_INTERFACE_NAME_FOR_S11_MME "MME_INTERFACE_NAME_FOR_S11_MME"
#define MME_CONFIG_STRING_IPV4_ADDRESS_FOR_S11_MME "MME_IPV4_ADDRESS_FOR_S11_MME"
#define MME_CONFIG_STRING_ASN1_VERBOSITY "VERBOSITY"
#define MME_CONFIG_STRING_ASN1_VERBOSITY_NONE "none"
#define MME_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING "annoying"
#define MME_CONFIG_STRING_ASN1_VERBOSITY_INFO "info"
#define MME_CONFIG_STRING_NAS_CONFIG "NAS"
#define MME_CONFIG_STRING_NAS_SUPPORTED_INTEGRITY_ALGORITHM_LIST "ORDERED_SUPPORTED_INTEGRITY_ALGORITHM_LIST"
#define MME_CONFIG_STRING_NAS_SUPPORTED_CIPHERING_ALGORITHM_LIST "ORDERED_SUPPORTED_CIPHERING_ALGORITHM_LIST"
#define NAS_CONFIG_SECURITY_ALGORITHMS_EEA0 0b000
#define NAS_CONFIG_SECURITY_ALGORITHMS_EEA1 0b001
#define NAS_CONFIG_SECURITY_ALGORITHMS_EEA2 0b010
#define NAS_CONFIG_SECURITY_ALGORITHMS_EEA3 0b011
#define NAS_CONFIG_SECURITY_ALGORITHMS_EEA4 0b100
#define NAS_CONFIG_SECURITY_ALGORITHMS_EEA5 0b101
#define NAS_CONFIG_SECURITY_ALGORITHMS_EEA6 0b110
#define NAS_CONFIG_SECURITY_ALGORITHMS_EEA7 0b111
#define NAS_CONFIG_SECURITY_ALGORITHMS_EIA0 0b000
#define NAS_CONFIG_SECURITY_ALGORITHMS_EIA1 0b001
#define NAS_CONFIG_SECURITY_ALGORITHMS_EIA2 0b010
#define NAS_CONFIG_SECURITY_ALGORITHMS_EIA3 0b011
#define NAS_CONFIG_SECURITY_ALGORITHMS_EIA4 0b100
#define NAS_CONFIG_SECURITY_ALGORITHMS_EIA5 0b101
#define NAS_CONFIG_SECURITY_ALGORITHMS_EIA6 0b110
#define NAS_CONFIG_SECURITY_ALGORITHMS_EIA7 0b111
typedef struct mme_config_s {
/* Reader/writer lock for this configuration */
pthread_rwlock_t rw_lock;
uint8_t verbosity_level;
char *config_file;
char *realm;
int realm_length;
uint32_t max_eNBs;
uint32_t max_ues;
uint8_t relative_capacity;
uint32_t mme_statistic_timer;
uint8_t emergency_attach_supported;
uint8_t unauthenticated_imsi_supported;
struct {
uint16_t nb_mme_gid;
uint16_t *mme_gid;
uint16_t nb_mmec;
uint8_t *mmec;
uint8_t nb_plmns;
uint16_t *plmn_mcc;
uint16_t *plmn_mnc;
uint16_t *plmn_mnc_len;
uint16_t *plmn_tac;
} gummei;
struct {
uint16_t in_streams;
uint16_t out_streams;
} sctp_config;
struct {
uint16_t port_number;
} gtpv1u_config;
struct {
uint16_t port_number;
uint8_t outcome_drop_timer_sec;
} s1ap_config;
struct {
uint32_t sgw_ip_address_for_S1u_S12_S4_up;
char *mme_interface_name_for_S1_MME;
uint32_t mme_ip_address_for_S1_MME;
char *mme_interface_name_for_S11;
uint32_t mme_ip_address_for_S11;
uint32_t sgw_ip_address_for_S11;
} ipv4;
struct {
uint32_t queue_size;
char *log_file;
} itti_config;
struct {
uint8_t prefered_integrity_algorithm[8];
uint8_t prefered_ciphering_algorithm[8];
} nas_config;
} mme_config_t;
extern mme_config_t mme_config;
int mme_config_find_mnc_length(const char mcc_digit1P,
const char mcc_digit2P,
const char mcc_digit3P,
const char mnc_digit1P,
const char mnc_digit2P,
const char mnc_digit3P);
int config_parse_opt_line(int argc, char *argv[], mme_config_t *mme_config);
#define config_read_lock(mMEcONFIG) pthread_rwlock_rdlock(&(mMEcONFIG)->rw_lock)
#define config_write_lock(mMEcONFIG) pthread_rwlock_wrlock(&(mMEcONFIG)->rw_lock)
#define config_unlock(mMEcONFIG) pthread_rwlock_unlock(&(mMEcONFIG)->rw_lock)
//int yyparse(struct mme_config_s *mme_config_p);
#endif /* __UTILS_MME_CONFIG__H__ */

View File

@@ -1,127 +0,0 @@
/*
* 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
*/
#ifndef MME_DEFAULT_VALUES_H_
#define MME_DEFAULT_VALUES_H_
/*******************************************************************************
* Timer Constants
******************************************************************************/
#define MME_STATISTIC_TIMER_S (60)
/*******************************************************************************
* GTPV1 User Plane Constants
******************************************************************************/
#define GTPV1_U_PORT_NUMBER (2152)
/*******************************************************************************
* S1AP Constants
******************************************************************************/
#define S1AP_PORT_NUMBER (36412) ///< S1AP SCTP IANA ASSIGNED Port Number
#define S1AP_SCTP_PPID (18) ///< S1AP SCTP Payload Protocol Identifier (PPID)
#define S1AP_OUTCOME_TIMER_DEFAULT (5) ///< S1AP Outcome drop timer (s)
/*******************************************************************************
* SCTP Constants
******************************************************************************/
/*
#define SCTP_RECV_BUFFER_SIZE (1 << 16)
#define SCTP_OUT_STREAMS (32)
#define SCTP_IN_STREAMS (32)
#define SCTP_MAX_ATTEMPTS (5)
*/
/*******************************************************************************
* MME global definitions
******************************************************************************/
#define MAX_NUMBER_OF_ENB (2)
#define MAX_NUMBER_OF_UE (64)
#define MMEC (0)
#define MMEGID (0)
#define PLMN_MCC (208)
#define PLMN_MNC (34)
#define PLMN_MNC_LEN (2)
#define PLMN_TAC (0)
#define RELATIVE_CAPACITY (15)
/*******************************************************************************
* IPv4 Constants
******************************************************************************/
/* Default network card to use for IPV4 packets forwarding.
* up stands for user-plane.
* cp stands for control-plane
*
* +-----------+ +------+ +-----------+
* | eNB +------+ | ovs | VLAN 1+------+ MME |
* | |cpenb0+------------------+cpmme0| |
* | +------+ |bridge| +------+ |
* | |upenb0+-------+ | | |
* +-----------+------+ | | | +-+------+--+
* +---|--+ |s11mme|
* | +---+--+
* | VLAN3 | (optional)
* | +---+--+
* | |s11sgw|
* | +-+------+--+
* | | S+P-GW |
* | VLAN2 +------+ +--------+
* +----------+upsgw0| |pgwsgi0 +
* +------+ +--------+
* | |
* +-----------+
*/
#define DEFAULT_SGW_INTERFACE_NAME_FOR_S11 ("s11sgw")
#define DEFAULT_SGW_IP_ADDRESS_FOR_S11 ("192.168.10.1")
#define DEFAULT_SGW_IP_NETMASK_FOR_S11 24
#define DEFAULT_SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP ("upsgw0")
#define DEFAULT_SGW_IP_ADDRESS_FOR_S1U_S12_S4_UP ("192.168.1.1")
#define DEFAULT_SGW_IP_NETMASK_FOR_S1U_S12_S4_UP 24
#define DEFAULT_SGW_INTERFACE_NAME_FOR_S5_S8_UP ("upsgw1")
#define DEFAULT_SGW_IP_ADDRESS_FOR_S5_S8_UP ("192.168.5.2")
#define DEFAULT_SGW_IP_NETMASK_FOR_S5_S8_UP 24
#define DEFAULT_PGW_INTERFACE_NAME_FOR_S5_S8 ("uppgw0")
#define DEFAULT_PGW_IP_ADDRESS_FOR_S5_S8 ("192.168.5.1")
#define DEFAULT_PGW_IP_NETMASK_FOR_S5_S8 24
#define DEFAULT_PGW_INTERFACE_NAME_FOR_SGI ("eth0")
#define DEFAULT_PGW_IP_ADDR_FOR_SGI ("192.168.14.17")
#define DEFAULT_PGW_IP_NETMASK_FOR_SGI 24
#define DEFAULT_MME_INTERFACE_NAME_FOR_S11 ("s11mme") ///< MME control plane interface
#define DEFAULT_MME_IP_ADDRESS_FOR_S11 ("192.168.10.2") ///< MME control plane IP address
#define DEFAULT_MME_IP_NETMASK_FOR_S11 24;
#define DEFAULT_MME_INTERFACE_NAME_FOR_S1_MME ("cpmme0") ///< MME control plane interface
#define DEFAULT_MME_IP_ADDRESS_FOR_S1_MME ("192.168.11.1") ///< MME control plane IP address
#define DEFAULT_MME_IP_NETMASK_FOR_S1_MME 24;
#endif /* MME_DEFAULT_VALUES_H_ */

View File

@@ -1,130 +0,0 @@
/* Lex configuration parser.
*
* This file defines the token for parsing the configuration file
*
* Note : This module is NOT thread-safe. All processing must be done from one thread only.
*/
%{
#include <stdio.h>
#include "mme_config.h"
/* Include yacc tokens definitions */
#include "mme_parser.h"
/* Update the column information */
#ifdef DEBUG_LEX
#define YY_USER_ACTION { \
yylloc->first_column = yylloc->last_column + 1; \
yylloc->last_column = yylloc->first_column + yyleng - 1; \
TRACE_DEBUG(FULL, \
"(%d:%d-%d:%d) matched rule %d, length=%d, txt='%s'\n", \
yylloc->first_line, yylloc->first_column, \
yylloc->last_line, yylloc->last_column, \
yy_act, yyleng, yytext); \
}
#else /* DEBUG_LEX */
#define YY_USER_ACTION { \
yylloc->first_column = yylloc->last_column + 1; \
yylloc->last_column = yylloc->first_column + yyleng - 1; \
}
#endif
#define YY_NO_INPUT
%}
%option bison-bridge bison-locations
%option noyywrap
%option nounput
/* Quoted string. Multilines do not match. */
qstring \"[^\"\n]*\"
%%
/* List of patterns and actions */
<*>\n {
/* Update the line count */
yylloc->first_line++;
yylloc->last_line++;
yylloc->last_column=0;
}
<*>([[:space:]]{-}[\n])+ ; /* Eat all spaces, not new lines */
<*>#.*$ ; /* Eat all comments */
{qstring} {
/* First copy the string without the quotes for use in the yacc parser */
if ((yylval->string = strdup(yytext+1)) == NULL) { /* This allocates one useless tail char but... it's easier :D */
return LEX_ERROR;/* on error, trig an error in yacc parser */
}
yylval->string[yyleng-2] = '\0';
/* the yacc parser will check the string is valid */
return QSTRING;
}
[[:digit:]]+ {
/* Convert this to an integer value */
int ret = sscanf(yytext, "%i", &yylval->integer);
if (ret != 1) {
/* No matching: an error occurred */
fprintf(stderr, "Unable to convert the value '%s' to a valid number: %s\n",
yytext, strerror(errno));
return LEX_ERROR; /* trig an error in yacc parser */
/* Maybe we could REJECT instead of failing here? */
}
return INTEGER;
}
/* Full words tokens (keywords) */
(?i:"EMERGENCY_ATTACH_SUPPORTED") { return EMERGENCY_ATTACH_SUPPORTED; }
(?i:"UNAUTHENTICATED_IMSI_SUPPORTED") { return UNAUTHENTICATED_IMSI_SUPPORTED; }
(?i:"MAXENB") { return MAX_ENB; }
(?i:"MAXUE") { return MAX_UE; }
(?i:"S6A_CONF") { return S6A_CONF; }
(?i:"ITTI_QUEUE_SIZE") { return ITTI_QUEUE_SIZE; }
(?i:"SCTP_INSTREAMS") { return SCTP_INSTREAMS; }
(?i:"SCTP_OUTSTREAMS") { return SCTP_OUTSTREAMS; }
(?i:"MME_CODE") { return MME_CODE; }
(?i:"MME_GID") { return MME_GID; }
(?i:"REALM") { return REALM; }
(?i:"PLMN") { return PLMN_Y; }
(?i:"RELATIVE_CAPACITY") { return RELATIVE_CAP; }
(?i:"S1AP_OUTCOME_TIMER") { return S1AP_OUTCOME_TIMER; }
(?i:"MME_STATISTIC_TIMER") { return MME_STATISTIC_TIMER; }
(?i:"SGW_INTERFACE_NAME_FOR_S11") { return SGW_INTERFACE_NAME_FOR_S11; }
(?i:"SGW_IP_ADDRESS_FOR_S11") { return SGW_IP_ADDRESS_FOR_S11; }
(?i:"SGW_IP_NETMASK_FOR_S11") { return SGW_IP_NETMASK_FOR_S11; }
(?i:"SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP") { return SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP; }
(?i:"SGW_IP_ADDRESS_FOR_S1U_S12_S4_UP") { return SGW_IP_ADDRESS_FOR_S1U_S12_S4_UP; }
(?i:"SGW_IP_NETMASK_FOR_S1U_S12_S4_UP") { return SGW_IP_NETMASK_FOR_S1U_S12_S4_UP; }
(?i:"SGW_INTERFACE_NAME_FOR_S5_S8_UP") { return SGW_INTERFACE_NAME_FOR_S5_S8_UP; }
(?i:"SGW_IP_ADDRESS_FOR_S5_S8_UP") { return SGW_IP_ADDRESS_FOR_S5_S8_UP; }
(?i:"SGW_IP_NETMASK_FOR_S5_S8_UP") { return SGW_IP_NETMASK_FOR_S5_S8_UP; }
(?i:"PGW_INTERFACE_NAME_FOR_S5_S8") { return PGW_INTERFACE_NAME_FOR_S5_S8; }
(?i:"PGW_IP_ADDRESS_FOR_S5_S8") { return PGW_IP_ADDRESS_FOR_S5_S8; }
(?i:"PGW_IP_NETMASK_FOR_S5_S8") { return PGW_IP_NETMASK_FOR_S5_S8; }
(?i:"PGW_INTERFACE_NAME_FOR_SGI") { return PGW_INTERFACE_NAME_FOR_SGI; }
(?i:"PGW_IP_ADDR_FOR_SGI") { return PGW_IP_ADDR_FOR_SGI; }
(?i:"PGW_IP_NETMASK_FOR_SGI") { return PGW_IP_NETMASK_FOR_SGI; }
(?i:"MME_INTERFACE_NAME_FOR_S1_MME") { return MME_INTERFACE_NAME_FOR_S1_MME; }
(?i:"MME_IP_ADDRESS_FOR_S1_MME") { return MME_IP_ADDRESS_FOR_S1_MME; }
(?i:"MME_IP_NETMASK_FOR_S1_MME") { return MME_IP_NETMASK_FOR_S1_MME; }
(?i:"MME_INTERFACE_NAME_FOR_S11_MME") { return MME_INTERFACE_NAME_FOR_S11_MME; }
(?i:"MME_IP_ADDRESS_FOR_S11_MME") { return MME_IP_ADDRESS_FOR_S11_MME; }
(?i:"MME_IP_NETMASK_FOR_S11_MME") { return MME_IP_NETMASK_FOR_S11_MME; }
/* Valid single characters for yyparse */
<*>[.=,:;{}] { return yytext[0]; }
<*>[[:alnum:]]+ | /* This rule is only useful to print a complete token in error messages */
/* Unrecognized character */
<*>. {
fprintf(stderr, "Unrecognized text on line %d col %d: '%s'.\n",
yylloc->first_line, yylloc->first_column, yytext);
return LEX_ERROR;
}
%%

View File

@@ -13,9 +13,6 @@ cd cmake_targets
#Execution instuctions (Currently running eNB (VNF) and UE side (PNF) on the same machine using the loopback interface)
cd cmake_targets/tools
# Loading nasmesh
source init_nas_nos1
# Add a new loopback interface address
sudo ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up

View File

@@ -1,157 +0,0 @@
include $(OPENAIR_DIR)/common/utils/Makefile.inc
TOP_DIR = $(OPENAIR1_DIR)
OPENAIR1_TOP = $(OPENAIR1_DIR)
OPENAIR2_TOP = $(OPENAIR2_DIR)
OPENAIR3_TOP = $(OPENAIR3_DIR)
OPENAIR3 = $(OPENAIR3_DIR)
CFLAGS += -m32 -DPHYSIM -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -I/usr/include/X11
ASN1_MSG_INC = $(OPENAIR2_DIR)/RRC/LITE/MESSAGES
CFLAGS += -DOPENAIR_LTE #-DOFDMA_ULSCH -DIFFT_FPGA -DIFFT_FPGA_UE
CFLAGS += -DMAC_CONTEXT=1 -DPHY_CONTEXT=1
CFLAGS += -DEMIT_ASN_DEBUG=1
ifndef OPENAIR2
OPENAIR2=1
endif
# activate OCG and libxml only under linux
ifeq ($(linux),1)
CFLAGS += -I/usr/include/libxml2 -L/usr/local/lib -I/usr/include/atlas -L/usr/X11R6/lib
CFLAGS += -DLINUX
endif
ifndef rrc_cellular
rrc_cellular = 0
rrc_cellular_eNB = 0
rrc_cellular_UE = 0
else
ifeq ($(eNB_flag),1)
rrc_cellular_eNB=1
endif
ifeq ($(UE_flag),1)
rrc_cellular_UE=1
endif
endif
ifdef DEBUG_PHY
CFLAGS += -DDEBUG_PHY
endif
#CFLAGS += -DPDCP_USE_NETLINK -DLINUX
#NAS_FLAG=1
#require kernel patch for oai driver to enable address autoconfiguration (IPv6 only)
ifdef ADDCONF
CFLAGS+=-DADDRCONF
endif
ifdef TRAFFIC_TM5
CFLAGS += -DRLC_UM_TEST_TRAFFIC=1 -DFULL_BUFFER=1
endif
include $(OPENAIR1_DIR)/PHY/Makefile.inc
include $(OPENAIR1_DIR)/SCHED/Makefile.inc
include $(OPENAIR2_DIR)/LAYER2/Makefile.inc
include $(OPENAIR1_DIR)/SIMULATION/ETH_TRANSPORT/Makefile.inc
include $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc
include $(OPENAIR2_DIR)/RRC/NAS/Makefile.inc
include $(OPENAIR2_DIR)/UTIL/Makefile.inc
ASN1_MSG_OBJS1=$(addprefix $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/, $(ASN1_MSG_OBJS))
#L2_OBJS =
#EXTRA_CFLAGS =
export IS_REL10=$(shell if [ -f .lock-rel10 ] ; then echo "1" ; else echo "0" ; fi)
export IS_REL8=$(shell if [ -f .lock-rel8 ] ; then echo "1" ; else echo "0" ; fi)
ifdef Rel10
CFLAGS += -DRel10
ifeq ($(IS_REL10), 0)
$(shell cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1c/ASN1_files/ ; rm EUTRA-RRC-Definitions.asn ; ln -s EUTRA-RRC-Definitions-a20.asn EUTRA-RRC-Definitions.asn ; cd $(OPENAIR_TARGETS)/TEST/PACKET_TRACER/ ; rm -f $(ASN1_MSG_OBJS1) ; rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc.generated ; rm -f $(L2_OBJS) ; touch .lock-rel10 ; rm .lock-rel8 ;)
endif
else # default is rel 8
ifeq ($(IS_REL8), 0)
$(shell cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1c/ASN1_files/ ; rm EUTRA-RRC-Definitions.asn ; ln -s EUTRA-RRC-Definitions-86.asn EUTRA-RRC-Definitions.asn ; cd $(OPENAIR_TARGETS)/TEST/PACKET_TRACER/ ; rm -f $(ASN1_MSG_OBJS1) ; rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc.generated ; rm -f $(L2_OBJS); rm -f *.o ; rm -f oaisim ; touch .lock-rel8 ; rm .lock-rel10 ; )
endif
endif
export IS_REL10=$(shell if [ -f .lock-rel10 ] ; then echo "1" ; else echo "0" ; fi)
export IS_REL8=$(shell if [ -f .lock-rel8 ] ; then echo "1" ; else echo "0" ; fi)
PT_OBJS = pt.o
SIMULATION_OBJS += $(TOP_DIR)/SIMULATION/TOOLS/taus.o
SIMULATION_OBJS += $(TOP_DIR)/SIMULATION/TOOLS/rangen_double.o
OBJ = $(PHY_OBJS) $(SIMULATION_OBJS) $(SCHED_OBJS) $(L2_OBJS) $(TOOLS_OBJS) $(STATS_OBJS) $(ASN1_MSG_OBJS1) $(NAS_OBJS) $(INT_OBJS) $(UTIL_OBJ)
OBJ += $(OPENAIR_TARGETS)/SIMU/USER/init_lte.o
all: pt
printvars:
@echo LINUX variable is $(linux)
@echo rrc_cellular variable is $(rrc_cellular)
@echo EXTRA_CFLAGS = $(EXTRA_CFLAGS)
@echo OAI NETLINK FLAG is $(NAS_FLAG)
@echo SSE3 proc is $(SSE3PROC)
@echo IS_REL_8 is $(IS_REL_8)
@echo IS_REL_10 is $(IS_REL_10)
$(OBJ): %.o : %.c
@echo Compiling $<
$(CC) -c $(CFLAGS) $(EXTRA_CFLAGS) -DPHY_CONTEXT=1 -I$(TOP_DIR) $(L2_incl) $(UTIL_incl) -I$(ASN1_MSG_INC) -o $@ $<
pt: $(OBJ) pt.c
@echo "Compiling pt.c ..."
@$(CC) pt.c -I$(TOP_DIR) $(L2_incl) $(UTIL_incl) -I$(ASN1_MSG_INC) -o pt $(CFLAGS) $(EXTRA_CFLAGS) $(OBJ) -lm -lblas -lpthread -lxml2 -lX11 -lXpm -lrt -lforms -llapack_atlas
ifeq ($(rrc_cellular_eNB),1)
mv oaisim oaisim_eNB
endif
ifeq ($(rrc_cellular_UE),1)
mv oaisim oaisim_UE
endif
nasmesh_fix:
(cd $(OPENAIR2_DIR) && make nasmesh_netlink_address_fix.ko)
(sudo insmod $(OPENAIR2_DIR)/NAS/DRIVER/MESH/nasmesh.ko)
nasmesh_nl:
(cd $(OPENAIR2_DIR) && make nasmesh_netlink.ko)
(sudo insmod $(OPENAIR2_DIR)/NAS/DRIVER/MESH/nasmesh.ko)
rb_tool:
(cd $(OPENAIR2_DIR)/NAS/DRIVER/MESH/RB_TOOL && make)
nasmesh_install:
(sudo rmmod nasmesh)
(sudo insmod $(OPENAIR2_DIR)/NAS/DRIVER/MESH/nasmesh.ko)
clean:
rm -f oaisim
rm -f $(OBJ)
rm -f *.o
rm -f *.exe*
cleanl1:
rm -f oaisim
rm -f $(PHY_OBJS) $(SCHED_OBJS)
rm -f *.o
rm -f *.exe
cleanl2:
rm -f $(L2_OBJS)
cleanasn1:
rm -f $(ASN1_MSG_OBJS1)
rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc.generated
print:
@echo $(CFLAGS)
@echo $(EXTRA_CFLAGS)
@echo $(OBJ)
showcflags:
@echo $(CFLAGS)

View File

@@ -1,35 +0,0 @@
This utility allows you to inject packets into the Openair4G stack (UE for the moment) or generate packets
from different parts of the stack.
To compile:
make pt
To get help
./pt --help
Some pregenerated messages (RRC and MAC) can be found in the PACKET_TRACER/messages directory. Here are some
usage examples:
To generate RRC messages (e.g. SIBx)
./pt --eNB_RRC --RRCSIB2_3
./pt --eNB_RRC --RRCConnectionReconfiguration
./pt --UE_RRC --RRCConnectionRequest
To inject packets into the OpenAir4G stack (This works for UE receiver only for now, with control-plane messasges)
./pt --eNB_MAC -I messages/Msg4.txt
./pt -I messages/rrcconnectionsetup.txt -J messages/rrcconnectionreconfiguration.txt --eNB_RRC --RRCConnectionReconfiguration
./pt -I messages/rrcconnectionsetup.txt --eNB_RRC --RRCConnectionSetup
To be done:
- user-plane tests, in particular out-of-order segments to (MAC->RLC)

View File

@@ -1 +0,0 @@
1C5AF0FA9E3966

View File

@@ -1 +0,0 @@
21591FA00404200602013D2C3FAC50083A101700300007888000080102900E08484A0202020000000000605A0AA1A3BB4B932B632B9B982808A0A0A322805FB007888000080891A2B3C353E0FA897844866E926E0D80100021F756A900

View File

@@ -1 +0,0 @@
3F0060129B26E0D9E1C952C860C0827030

View File

@@ -1 +0,0 @@
5040040300010000001C1650902080850000

View File

@@ -1 +0,0 @@
00000C60FD6C8160C002A00200141000029AA55696D0C72944C1C000

Some files were not shown because too many files have changed in this diff Show More