mirror of https://github.com/PentHertz/srsLTE.git
Merge branch 'next' into epc_sigpipe
This commit is contained in:
commit
11b51e7cb4
|
@ -1,6 +1,10 @@
|
|||
Change Log for Releases
|
||||
==============================
|
||||
|
||||
## 18.03.1
|
||||
* Fixed compilation for NEON
|
||||
* Fixed logging and RLC AM issue
|
||||
|
||||
## 18.03
|
||||
* Many bug-fixes and improved stability and performance in all parts
|
||||
|
||||
|
|
|
@ -131,6 +131,16 @@ else(POLARSSL_FOUND)
|
|||
endif (MBEDTLS_FOUND)
|
||||
endif(POLARSSL_FOUND)
|
||||
|
||||
# Hard-SIM support
|
||||
find_package(PCSCLite)
|
||||
if (PCSCLITE_FOUND)
|
||||
message(STATUS "Building with PCSC support.")
|
||||
add_definitions(-DHAVE_PCSC)
|
||||
set(HAVE_PCSC TRUE)
|
||||
include_directories(${PCSCLITE_INCLUDE_DIR})
|
||||
#link_directories(${PCSCLITE_LIBRARIES})
|
||||
endif (PCSCLITE_FOUND)
|
||||
|
||||
# UHD
|
||||
find_package(UHD)
|
||||
if(UHD_FOUND)
|
||||
|
@ -214,6 +224,13 @@ set(INCLUDE_DIR include)
|
|||
set(DOC_DIR "share/doc/${CPACK_PACKAGE_NAME}")
|
||||
set(DATA_DIR share/${CPACK_PACKAGE_NAME})
|
||||
|
||||
# Auto-generate config install helper and mark for installation
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/cmake/modules/SRSLTE_install_configs.sh.in
|
||||
${CMAKE_BINARY_DIR}/srslte_install_configs.sh
|
||||
)
|
||||
install(PROGRAMS ${CMAKE_BINARY_DIR}/srslte_install_configs.sh DESTINATION ${RUNTIME_DIR})
|
||||
|
||||
########################################################################
|
||||
# Compiler specific setup
|
||||
########################################################################
|
||||
|
@ -226,7 +243,7 @@ macro(ADD_CXX_COMPILER_FLAG_IF_AVAILABLE flag have)
|
|||
endmacro(ADD_CXX_COMPILER_FLAG_IF_AVAILABLE)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${GCC_ARCH} -Wall -Wno-comment -Wno-reorder -Wno-unused-but-set-variable -Wno-unused-variable -Wformat -std=c++03")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${GCC_ARCH} -Wall -Wno-comment -Wno-reorder -Wno-unused-but-set-variable -Wno-unused-variable -Wformat -Wmissing-field-initializers -Wtype-limits -std=c++03")
|
||||
|
||||
find_package(SSE)
|
||||
if (HAVE_AVX2)
|
||||
|
@ -243,7 +260,7 @@ endif(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clan
|
|||
ADD_CXX_COMPILER_FLAG_IF_AVAILABLE("-Werror=incompatible-pointer-types" HAVE_ERROR_INCOMPATIBLE)
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=${GCC_ARCH} -Wall -Wno-comment -Wno-write-strings -Wno-format-extra-args -Winline -Wno-unused-result -Wno-format -std=c99 -D_GNU_SOURCE")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=${GCC_ARCH} -Wall -Wno-comment -Wno-write-strings -Winline -Wno-unused-result -Wformat -Wmissing-field-initializers -Wtype-limits -std=c99 -D_GNU_SOURCE")
|
||||
|
||||
if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb -O0 -DDEBUG_MODE -DBUILD_TYPE_DEBUG")
|
||||
|
@ -274,6 +291,10 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
|||
endif(HAVE_AVX)
|
||||
endif (HAVE_AVX2)
|
||||
|
||||
if (HAVE_FMA)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfma -DLV_HAVE_FMA")
|
||||
endif (HAVE_FMA)
|
||||
|
||||
if (HAVE_AVX512)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx512f -mavx512cd -DLV_HAVE_AVX512")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx512f -mavx512cd -DLV_HAVE_AVX512")
|
||||
|
|
38
LICENSE
38
LICENSE
|
@ -658,4 +658,40 @@ specific requirements.
|
|||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
The license terms used for the scard class (in pcsc_usim) derived from wpa_supplicant
|
||||
-------------------------------------------------------------------------------------
|
||||
|
||||
Modified BSD license (no advertisement clause):
|
||||
|
||||
Copyright (c) 2002-2017, Jouni Malinen <j@w1.fi> and contributors
|
||||
All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name(s) of the above-listed copyright holder(s) nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -108,6 +108,7 @@ Note that depending on your flavor and version of Linux, the actual package name
|
|||
|
||||
* Optional requirements:
|
||||
* srsgui: https://github.com/srslte/srsgui - for real-time plotting.
|
||||
* libpcsclite-dev https://pcsclite.apdu.fr/ - for accessing smart card readers
|
||||
|
||||
* RF front-end driver:
|
||||
* UHD: https://github.com/EttusResearch/uhd
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
# - Find PCSC-Lite
|
||||
# Find the native PCSC-Lite includes and library
|
||||
#
|
||||
# PCSCLITE_INCLUDE_DIR - where to find winscard.h, wintypes.h, etc.
|
||||
# PCSCLITE_LIBRARIES - List of libraries when using PCSC-Lite.
|
||||
# PCSCLITE_FOUND - True if PCSC-Lite found.
|
||||
|
||||
FIND_PACKAGE(PkgConfig)
|
||||
PKG_CHECK_MODULES(PC_PCSCLITE libpcsclite)
|
||||
|
||||
IF(NOT PCSCLITE_FOUND)
|
||||
|
||||
FIND_PATH(PCSCLITE_INCLUDE_DIR
|
||||
NAMES winscard.h
|
||||
HINTS /usr/include/PCSC
|
||||
/usr/local/include/PCSC
|
||||
${PC_PCSCLITE_INCLUDEDIR}
|
||||
${PC_PCSCLITE_INCLUDE_DIRS}
|
||||
${PC_PCSCLITE_INCLUDE_DIRS}/PCSC
|
||||
${CMAKE_INSTALL_PREFIX}/include
|
||||
)
|
||||
FIND_LIBRARY(PCSCLITE_LIBRARY NAMES pcsclite libpcsclite PCSC
|
||||
HINTS ${PC_PCSCLITE_LIBDIR}
|
||||
${PC_PCSCLITE_LIBRARY_DIRS}
|
||||
${CMAKE_INSTALL_PREFIX}/lib
|
||||
${CMAKE_INSTALL_PREFIX}/lib64
|
||||
PATHS /usr/local/lib
|
||||
/usr/local/lib64
|
||||
/usr/lib
|
||||
/usr/lib64
|
||||
)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set PCSCLITE_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCSCLITE DEFAULT_MSG PCSCLITE_LIBRARY PCSCLITE_INCLUDE_DIR)
|
||||
|
||||
IF(PCSCLITE_FOUND)
|
||||
SET(PCSCLITE_LIBRARIES ${PCSCLITE_LIBRARY})
|
||||
ELSE(PCSCLITE_FOUND)
|
||||
SET(PCSCLITE_LIBRARIES )
|
||||
ENDIF(PCSCLITE_FOUND)
|
||||
|
||||
message(STATUS "PCSC LIBRARIES: " ${PCSCLITE_LIBRARY})
|
||||
message(STATUS "PCSC INCLUDE DIRS: " ${PCSCLITE_INCLUDE_DIR})
|
||||
|
||||
MARK_AS_ADVANCED( PCSCLITE_LIBRARY PCSCLITE_INCLUDE_DIR )
|
||||
ENDIF(NOT PCSCLITE_FOUND)
|
|
@ -20,5 +20,5 @@
|
|||
|
||||
SET(SRSLTE_VERSION_MAJOR 18)
|
||||
SET(SRSLTE_VERSION_MINOR 3)
|
||||
SET(SRSLTE_VERSION_PATCH 0)
|
||||
SET(SRSLTE_VERSION_PATCH 1)
|
||||
SET(SRSLTE_VERSION_STRING "${SRSLTE_VERSION_MAJOR}.${SRSLTE_VERSION_MINOR}.${SRSLTE_VERSION_PATCH}")
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Auto-updated by CMake with actual install path
|
||||
SRSLTE_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}/${DATA_DIR}"
|
||||
|
||||
# Default folder where configs go
|
||||
dest_folder="$HOME/.srs"
|
||||
|
||||
install_file(){
|
||||
source_path="$SRSLTE_INSTALL_DIR/$1"
|
||||
dest_path=$(echo "$dest_folder/$1" | sed 's/\.[^.]*$//') # Strip .example from filename
|
||||
|
||||
# Check if config file already exists in location
|
||||
if [ -f $dest_path ]; then
|
||||
echo " - $dest_path already exists. Skipping it."
|
||||
return
|
||||
fi
|
||||
|
||||
# Check if config file exists in source location
|
||||
if [ -f $source_path ]; then
|
||||
echo " - Installing $1 in $dest_path"
|
||||
cp $source_path $dest_path
|
||||
|
||||
# Set file ownership to user calling sudo
|
||||
if [ $SUDO_USER ]; then
|
||||
user=$SUDO_USER
|
||||
chown $user:$user $dest_path
|
||||
fi
|
||||
else
|
||||
echo " - $source_path doesn't exists. Skipping it."
|
||||
fi
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
# Install all srsLTE config files
|
||||
echo "Installing srsLTE configuration files:"
|
||||
|
||||
# Make sure the target directory exists
|
||||
if [ ! -d "$dest_folder" ]; then
|
||||
echo " - Creating srsLTE config folder $dest_folder"
|
||||
mkdir $dest_folder
|
||||
fi
|
||||
|
||||
|
||||
install_file "ue.conf.example"
|
||||
install_file "enb.conf.example"
|
||||
install_file "sib.conf.example"
|
||||
install_file "rr.conf.example"
|
||||
install_file "drb.conf.example"
|
||||
install_file "epc.conf.example"
|
||||
install_file "mbms.conf.example"
|
||||
install_file "user_db.csv.example"
|
||||
|
||||
echo "Done."
|
|
@ -0,0 +1,11 @@
|
|||
srslte (18.05~SNAPSHOT-0ubuntu2) bionic; urgency=medium
|
||||
|
||||
* Update pkg deps
|
||||
|
||||
-- Andre Puschmann <andre@softwareradiosystems.com> Tue, 01 June 2018 15:10:00 +0200
|
||||
|
||||
srslte (18.05~SNAPSHOT-0ubuntu1) bionic; urgency=medium
|
||||
|
||||
* Initial release of deb's
|
||||
|
||||
-- Andre Puschmann <andre@softwareradiosystems.com> Tue, 01 June 2018 14:10:00 +0200
|
|
@ -0,0 +1 @@
|
|||
9
|
|
@ -0,0 +1,14 @@
|
|||
Source: srslte
|
||||
Section: misc
|
||||
Priority: optional
|
||||
Maintainer: Andre Puschmann <andre@softwareradiosystems.com>
|
||||
Build-Depends: debhelper (>= 9), dh-exec, cmake, build-essential, libfftw3-dev, libmbedtls-dev, libboost-program-options-dev, libconfig++-dev, libsctp-dev, libuhd-dev, uhd-host
|
||||
Standards-Version: 4.1.1
|
||||
Homepage: https://github.com/srsLTE/srsLTE/
|
||||
|
||||
Package: srslte
|
||||
Architecture: any
|
||||
Depends: libfftw3-3 (>= 3.3.3-1), libboost-program-options1.62.0 (>= 1.62.0), libmbedcrypto1 (>= 2.8.0-1), libconfig++9v5 (>= 1.5-0.2), libsctp1 (>= 1.0.16+dfsg-3), uhd-host (>= 3.9.2-1), libuhd003.010.003 (>= 3.10.3.0-2)
|
||||
Description: This is srsLTE, a free and open-source LTE software suite.
|
||||
This software allows you to run a full end-to-end, open-source LTE system.
|
||||
It contains a UE, eNB and EPC implementation.
|
|
@ -0,0 +1,516 @@
|
|||
Copyright (C) 2013-2016 Software Radio Systems Limited. All rights reserved.
|
||||
|
||||
The following copyright notices are for libraries used within srsLTE:
|
||||
|
||||
-----------------------------------------------------------
|
||||
FEC Library - Version 3.0.1 - August 7th, 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
COPYRIGHT
|
||||
|
||||
This package is copyright 2006 by Phil Karn, KA9Q. It may be used
|
||||
under the terms of the GNU Lesser General Public License (LGPL).
|
||||
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/make -f
|
||||
# Uncomment this to turn on verbose mode.
|
||||
export DH_VERBOSE=1
|
||||
|
||||
# This has to be exported to make some magic below work.
|
||||
export DH_OPTIONS
|
||||
|
||||
%:
|
||||
dh $@ --parallel
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure --buildsystem=cmake -- $(extraopts) $(CEPH_EXTRA_CMAKE_ARGS) -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
override_dh_auto_test:
|
||||
# skip executing tests
|
|
@ -0,0 +1 @@
|
|||
3.0 (quilt)
|
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/dh-exec
|
||||
srsue/ue.conf.example => usr/share/srslte/config/ue.conf
|
||||
srsenb/enb.conf.example => usr/share/srslte/config/enb.conf
|
||||
srsenb/rr.conf.example => usr/share/srslte/config/rr.conf
|
||||
srsenb/drb.conf.example => usr/share/srslte/config/drb.conf
|
||||
srsenb/sib.conf.example => usr/share/srslte/config/sib.conf
|
||||
srsepc/epc.conf.example => usr/share/srslte/config/epc.conf
|
||||
srsepc/mbms.conf.example => usr/share/srslte/config/mbms.conf
|
||||
srsepc/user_db.csv.example => usr/share/srslte/config/user_db.csv
|
|
@ -32,18 +32,18 @@ target_link_libraries(synch_file srslte_phy)
|
|||
|
||||
if(RF_FOUND)
|
||||
add_executable(pdsch_ue pdsch_ue.c)
|
||||
target_link_libraries(pdsch_ue srslte_phy srslte_rf pthread)
|
||||
target_link_libraries(pdsch_ue srslte_phy srslte_common srslte_rf pthread)
|
||||
|
||||
add_executable(pdsch_enodeb pdsch_enodeb.c)
|
||||
target_link_libraries(pdsch_enodeb srslte_phy srslte_rf pthread)
|
||||
target_link_libraries(pdsch_enodeb srslte_phy srslte_common srslte_rf pthread)
|
||||
else(RF_FOUND)
|
||||
add_definitions(-DDISABLE_RF)
|
||||
|
||||
add_executable(pdsch_ue pdsch_ue.c)
|
||||
target_link_libraries(pdsch_ue srslte_phy pthread)
|
||||
target_link_libraries(pdsch_ue srslte_common srslte_phy pthread)
|
||||
|
||||
add_executable(pdsch_enodeb pdsch_enodeb.c)
|
||||
target_link_libraries(pdsch_enodeb srslte_phy pthread)
|
||||
target_link_libraries(pdsch_enodeb srslte_common srslte_phy pthread)
|
||||
endif(RF_FOUND)
|
||||
|
||||
find_package(SRSGUI)
|
||||
|
|
|
@ -199,7 +199,12 @@ int main(int argc, char **argv) {
|
|||
srslte_ue_cellsearch_set_nof_valid_frames(&cs, cell_detect_config.nof_valid_pss_frames);
|
||||
}
|
||||
if (cell_detect_config.init_agc) {
|
||||
srslte_ue_sync_start_agc(&cs.ue_sync, srslte_rf_set_rx_gain_wrapper, cell_detect_config.init_agc);
|
||||
srslte_rf_info_t *rf_info = srslte_rf_get_info(&rf);
|
||||
srslte_ue_sync_start_agc(&cs.ue_sync,
|
||||
srslte_rf_set_rx_gain_wrapper,
|
||||
rf_info->min_rx_gain,
|
||||
rf_info->max_rx_gain,
|
||||
cell_detect_config.init_agc);
|
||||
}
|
||||
|
||||
for (freq=0;freq<nof_freqs && !go_exit;freq++) {
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include <signal.h>
|
||||
#include <srslte/phy/common/phy_common.h>
|
||||
#include <srslte/phy/phch/pdsch_cfg.h>
|
||||
|
||||
#include "srslte/common/gen_mch_tables.h"
|
||||
#include "srslte/srslte.h"
|
||||
|
||||
|
||||
|
@ -79,10 +79,10 @@ char mimo_type_str[32] = "single";
|
|||
uint32_t nof_tb = 1;
|
||||
uint32_t multiplex_pmi = 0;
|
||||
uint32_t multiplex_nof_layers = 1;
|
||||
|
||||
uint8_t mbsfn_sf_mask = 32;
|
||||
int mbsfn_area_id = -1;
|
||||
char *rf_args = "";
|
||||
float rf_amp = 0.8, rf_gain = 70.0, rf_freq = 2400000000;
|
||||
float rf_amp = 0.8, rf_gain = 60.0, rf_freq = 2400000000;
|
||||
|
||||
float output_file_snr = +INFINITY;
|
||||
|
||||
|
@ -123,7 +123,7 @@ int prbset_orig = 0;
|
|||
|
||||
|
||||
#define DATA_BUFF_SZ 1024*1024
|
||||
uint8_t *data[2], data2[DATA_BUFF_SZ];
|
||||
uint8_t *data_mbms, *data[2], data2[DATA_BUFF_SZ];
|
||||
uint8_t data_tmp[DATA_BUFF_SZ];
|
||||
|
||||
void usage(char *prog) {
|
||||
|
@ -145,7 +145,7 @@ void usage(char *prog) {
|
|||
printf("\t-x Transmission mode[single|diversity|cdd|multiplex] [Default %s]\n", mimo_type_str);
|
||||
printf("\t-b Precoding Matrix Index (multiplex mode only)* [Default %d]\n", multiplex_pmi);
|
||||
printf("\t-w Number of codewords/layers (multiplex mode only)* [Default %d]\n", multiplex_nof_layers);
|
||||
printf("\t-u listen TCP port for input data (-1 is random) [Default %d]\n", net_port);
|
||||
printf("\t-u listen TCP/UDP port for input data (if mbsfn is active then the stream is over mbsfn only) (-1 is random) [Default %d]\n", net_port);
|
||||
printf("\t-v [set srslte_verbose to debug, default none]\n");
|
||||
printf("\t-s output file SNR [Default %f]\n", output_file_snr);
|
||||
printf("\n");
|
||||
|
@ -154,7 +154,7 @@ void usage(char *prog) {
|
|||
|
||||
void parse_args(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "aglfmoncpvutxbwMs")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "aglfmoncpvutxbwMsB")) != -1) {
|
||||
|
||||
switch (opt) {
|
||||
case 'a':
|
||||
|
@ -206,6 +206,9 @@ void parse_args(int argc, char **argv) {
|
|||
case 's':
|
||||
output_file_snr = atof(argv[optind]);
|
||||
break;
|
||||
case 'B':
|
||||
mbsfn_sf_mask = atoi(argv[optind]);
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
|
@ -256,6 +259,8 @@ void base_init() {
|
|||
}
|
||||
bzero(data[i], sizeof(uint8_t) * SOFTBUFFER_SIZE);
|
||||
}
|
||||
data_mbms = srslte_vec_malloc(sizeof(uint8_t) * SOFTBUFFER_SIZE);
|
||||
|
||||
|
||||
/* init memory */
|
||||
for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
|
||||
|
@ -301,7 +306,7 @@ void base_init() {
|
|||
}
|
||||
|
||||
if (net_port > 0) {
|
||||
if (srslte_netsource_init(&net_source, "0.0.0.0", net_port, SRSLTE_NETSOURCE_TCP)) {
|
||||
if (srslte_netsource_init(&net_source, "127.0.0.1", net_port, SRSLTE_NETSOURCE_UDP)) {
|
||||
fprintf(stderr, "Error creating input UDP socket at port %d\n", net_port);
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -659,15 +664,21 @@ void *net_thread_fnc(void *arg) {
|
|||
n = srslte_netsource_read(&net_source, &data2[rpm], DATA_BUFF_SZ-rpm);
|
||||
if (n > 0) {
|
||||
// FIXME: I assume that both transport blocks have same size in case of 2 tb are active
|
||||
int nbytes = 1 + (pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs - 1) / 8;
|
||||
|
||||
int nbytes = 1 + (((mbsfn_area_id > -1)?(pmch_cfg.grant.mcs[0].tbs):(pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs)) - 1) / 8;
|
||||
rpm += n;
|
||||
INFO("received %d bytes. rpm=%d/%d\n",n,rpm,nbytes);
|
||||
wpm = 0;
|
||||
while (rpm >= nbytes) {
|
||||
// wait for packet to be transmitted
|
||||
sem_wait(&net_sem);
|
||||
memcpy(data[0], &data2[wpm], nbytes / (size_t) 2);
|
||||
memcpy(data[1], &data2[wpm], nbytes / (size_t) 2);
|
||||
if(mbsfn_area_id > -1){
|
||||
memcpy(data_mbms, &data2[wpm], nbytes);
|
||||
}
|
||||
else{
|
||||
memcpy(data[0], &data2[wpm], nbytes / (size_t) 2);
|
||||
memcpy(data[1], &data2[wpm], nbytes / (size_t) 2);
|
||||
}
|
||||
INFO("Sent %d/%d bytes ready\n", nbytes, rpm);
|
||||
rpm -= nbytes;
|
||||
wpm += nbytes;
|
||||
|
@ -714,6 +725,11 @@ int main(int argc, char **argv) {
|
|||
|
||||
parse_args(argc, argv);
|
||||
|
||||
uint8_t mch_table[10];
|
||||
bzero(&mch_table[0], sizeof(uint8_t)*10);
|
||||
if(mbsfn_area_id < -1) {
|
||||
generate_mcch_table(mch_table, mbsfn_sf_mask);
|
||||
}
|
||||
N_id_2 = cell.id % 3;
|
||||
sf_n_re = 2 * SRSLTE_CP_NORM_NSYMB * cell.nof_prb * SRSLTE_NRE;
|
||||
sf_n_samples = 2 * SRSLTE_SLOT_LEN(srslte_symbol_sz(cell.nof_prb));
|
||||
|
@ -739,10 +755,15 @@ int main(int argc, char **argv) {
|
|||
exit(-1);
|
||||
}
|
||||
if(mbsfn_area_id > -1) {
|
||||
if(srslte_refsignal_mbsfn_init(&mbsfn_refs, cell, mbsfn_area_id)) {
|
||||
if(srslte_refsignal_mbsfn_init(&mbsfn_refs, cell.nof_prb)) {
|
||||
fprintf(stderr, "Error initializing equalizer\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (srslte_refsignal_mbsfn_set_cell(&mbsfn_refs, cell, mbsfn_area_id)) {
|
||||
fprintf(stderr, "Error initializing MBSFNR signal\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(srslte_refsignal_cs_set_cell(&csr_refs, cell)){
|
||||
|
@ -801,7 +822,7 @@ int main(int argc, char **argv) {
|
|||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
pmch_cfg.grant.mcs[0].tbs = 1096;
|
||||
/* Initiate valid DCI locations */
|
||||
for (i=0;i<SRSLTE_NSUBFRAMES_X_FRAME;i++) {
|
||||
srslte_pdcch_ue_locations(&pdcch, locations[i], 30, i, cfi, UE_CRNTI);
|
||||
|
@ -830,13 +851,13 @@ int main(int argc, char **argv) {
|
|||
srslte_sss_put_slot(sf_idx ? sss_signal5 : sss_signal0, sf_symbols[0], cell.nof_prb,
|
||||
SRSLTE_CP_NORM);
|
||||
}
|
||||
|
||||
|
||||
/* Copy zeros, SSS, PSS into the rest of antenna ports */
|
||||
for (i = 1; i < cell.nof_ports; i++) {
|
||||
memcpy(sf_symbols[i], sf_symbols[0], sizeof(cf_t) * sf_n_re);
|
||||
}
|
||||
|
||||
if(sf_idx == 1 && mbsfn_area_id > -1){
|
||||
if(mch_table[sf_idx] == 1 && mbsfn_area_id > -1){
|
||||
srslte_refsignal_mbsfn_put_sf(cell, 0,csr_refs.pilots[0][sf_idx], mbsfn_refs.pilots[0][sf_idx], sf_symbols[0]);
|
||||
} else {
|
||||
for (i = 0; i < cell.nof_ports; i++) {
|
||||
|
@ -857,10 +878,10 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
/* Transmit PDCCH + PDSCH only when there is data to send */
|
||||
if (net_port > 0) {
|
||||
if ((net_port > 0) && (mch_table[sf_idx] == 1 && mbsfn_area_id > -1)) {
|
||||
send_data = net_packet_ready;
|
||||
if (net_packet_ready) {
|
||||
INFO("Transmitting packet\n");
|
||||
INFO("Transmitting packet from port\n");
|
||||
}
|
||||
} else {
|
||||
INFO("SF: %d, Generating %d random bits\n", sf_idx, pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs);
|
||||
|
@ -878,9 +899,8 @@ int main(int argc, char **argv) {
|
|||
send_data = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (send_data) {
|
||||
if(sf_idx != 1 || mbsfn_area_id < 0) { // PDCCH + PDSCH
|
||||
if(mch_table[sf_idx] == 0 || mbsfn_area_id < 0) { // PDCCH + PDSCH
|
||||
srslte_dci_format_t dci_format;
|
||||
switch(pdsch_cfg.mimo_type) {
|
||||
case SRSLTE_MIMO_TYPE_SINGLE_ANTENNA:
|
||||
|
@ -932,41 +952,46 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
}
|
||||
net_packet_ready = false;
|
||||
sem_post(&net_sem);
|
||||
if(mbsfn_area_id < 0){
|
||||
net_packet_ready = false;
|
||||
sem_post(&net_sem);
|
||||
}
|
||||
}
|
||||
}else{ // We're sending MCH on subframe 1 - PDCCH + PMCH
|
||||
|
||||
/* Encode PDCCH */
|
||||
INFO("Putting DCI to location: n=%d, L=%d\n", locations[sf_idx][0].ncce, locations[sf_idx][0].L);
|
||||
srslte_dci_msg_pack_pdsch(&ra_dl, SRSLTE_DCI_FORMAT1, &dci_msg, cell.nof_prb, cell.nof_ports, false);
|
||||
if (srslte_pdcch_encode(&pdcch, &dci_msg, locations[sf_idx][0], M_CRNTI, sf_symbols, sf_idx, cfi)) {
|
||||
fprintf(stderr, "Error encoding DCI message\n");
|
||||
exit(-1);
|
||||
}
|
||||
//INFO("Putting DCI to location: n=%d, L=%d\n", locations[sf_idx][0].ncce, locations[sf_idx][0].L);
|
||||
//srslte_dci_msg_pack_pdsch(&ra_dl, SRSLTE_DCI_FORMAT1, &dci_msg, cell.nof_prb, cell.nof_ports, false);
|
||||
//if (srslte_pdcch_encode(&pdcch, &dci_msg, locations[sf_idx][0], M_CRNTI, sf_symbols, sf_idx, cfi)) {
|
||||
// fprintf(stderr, "Error encoding DCI message\n");
|
||||
// exit(-1);
|
||||
// }
|
||||
/* Configure pmch_cfg parameters */
|
||||
srslte_ra_dl_grant_t grant;
|
||||
grant.tb_en[0] = true;
|
||||
grant.tb_en[1] = false;
|
||||
|
||||
grant.mcs[0].idx = 2;
|
||||
grant.mcs[0].mod = SRSLTE_MOD_QPSK;
|
||||
grant.nof_prb = cell.nof_prb;
|
||||
grant.sf_type = SRSLTE_SF_MBSFN;
|
||||
grant.Qm[0] = srslte_mod_bits_x_symbol(grant.mcs[0].mod);
|
||||
srslte_dl_fill_ra_mcs(&grant.mcs[0], cell.nof_prb);
|
||||
grant.Qm[0] = srslte_mod_bits_x_symbol(grant.mcs[0].mod);
|
||||
for(int i = 0; i < 2; i++){
|
||||
for(int j = 0; j < grant.nof_prb; j++){
|
||||
grant.prb_idx[i][j] = true;
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < grant.mcs[0].tbs/8;i++)
|
||||
{
|
||||
data_mbms[i] = i%255;
|
||||
}
|
||||
|
||||
|
||||
if (srslte_pmch_cfg(&pmch_cfg, cell, &grant, cfi, sf_idx)) {
|
||||
fprintf(stderr, "Error configuring PMCH\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
/* Encode PMCH */
|
||||
if (srslte_pmch_encode(&pmch, &pmch_cfg, softbuffers[0], data[0], mbsfn_area_id, sf_symbols)) {
|
||||
if (srslte_pmch_encode(&pmch, &pmch_cfg, softbuffers[0], data_mbms, mbsfn_area_id, sf_symbols)) {
|
||||
fprintf(stderr, "Error encoding PDSCH\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -984,13 +1009,14 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
/* Transform to OFDM symbols */
|
||||
if(sf_idx != 1 || mbsfn_area_id < 0){
|
||||
if(mch_table[sf_idx] == 0 || mbsfn_area_id < 0){
|
||||
for (i = 0; i < cell.nof_ports; i++) {
|
||||
srslte_ofdm_tx_sf(&ifft[i]);
|
||||
}
|
||||
}else{
|
||||
srslte_ofdm_tx_sf(&ifft_mbsfn);
|
||||
}
|
||||
|
||||
|
||||
/* send to file or usrp */
|
||||
if (output_file_name) {
|
||||
|
@ -1006,7 +1032,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
usleep(1000);
|
||||
} else {
|
||||
#ifndef DISABLE_RF
|
||||
#ifndef DISABLE_RF
|
||||
float norm_factor = (float) cell.nof_prb/15/sqrtf(pdsch_cfg.grant.nof_prb);
|
||||
for (i = 0; i < cell.nof_ports; i++) {
|
||||
srslte_vec_sc_prod_cfc(output_buffer[i], rf_amp * norm_factor, output_buffer[i], SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include "srslte/common/gen_mch_tables.h"
|
||||
#include <srslte/phy/common/phy_common.h>
|
||||
#include "srslte/phy/io/filesink.h"
|
||||
#include "srslte/srslte.h"
|
||||
|
@ -103,6 +104,7 @@ typedef struct {
|
|||
int decimate;
|
||||
int32_t mbsfn_area_id;
|
||||
uint8_t non_mbsfn_region;
|
||||
uint8_t mbsfn_sf_mask;
|
||||
int verbose;
|
||||
}prog_args_t;
|
||||
|
||||
|
@ -138,6 +140,7 @@ void args_default(prog_args_t *args) {
|
|||
args->cpu_affinity = -1;
|
||||
args->mbsfn_area_id = -1;
|
||||
args->non_mbsfn_region = 2;
|
||||
args->mbsfn_sf_mask = 32;
|
||||
}
|
||||
|
||||
void usage(prog_args_t *args, char *prog) {
|
||||
|
@ -185,7 +188,7 @@ void usage(prog_args_t *args, char *prog) {
|
|||
void parse_args(prog_args_t *args, int argc, char **argv) {
|
||||
int opt;
|
||||
args_default(args);
|
||||
while ((opt = getopt(argc, argv, "aAoglipPcOCtdDFRnvrfuUsSZyWMN")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "aAoglipPcOCtdDFRnvrfuUsSZyWMNB")) != -1) {
|
||||
switch (opt) {
|
||||
case 'i':
|
||||
args->input_file_name = argv[optind];
|
||||
|
@ -275,6 +278,9 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
|
|||
case 'N':
|
||||
args->non_mbsfn_region = atoi(argv[optind]);
|
||||
break;
|
||||
case 'B':
|
||||
args->mbsfn_sf_mask = atoi(argv[optind]);
|
||||
break;
|
||||
default:
|
||||
usage(args, argv[0]);
|
||||
exit(-1);
|
||||
|
@ -364,8 +370,11 @@ int main(int argc, char **argv) {
|
|||
go_exit = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t mch_table[10];
|
||||
bzero(&mch_table[0], sizeof(uint8_t)*10);
|
||||
if(prog_args.mbsfn_area_id < -1) {
|
||||
generate_mcch_table(mch_table, prog_args.mbsfn_sf_mask);
|
||||
}
|
||||
if(prog_args.cpu_affinity > -1) {
|
||||
|
||||
cpu_set_t cpuset;
|
||||
|
@ -385,7 +394,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
if (prog_args.net_port > 0) {
|
||||
if (srslte_netsink_init(&net_sink, prog_args.net_address, prog_args.net_port, SRSLTE_NETSINK_TCP)) {
|
||||
if (srslte_netsink_init(&net_sink, prog_args.net_address, prog_args.net_port, SRSLTE_NETSINK_UDP)) {
|
||||
fprintf(stderr, "Error initiating UDP socket to %s:%d\n", prog_args.net_address, prog_args.net_port);
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -591,7 +600,12 @@ int main(int argc, char **argv) {
|
|||
|
||||
#ifndef DISABLE_RF
|
||||
if (prog_args.rf_gain < 0) {
|
||||
srslte_ue_sync_start_agc(&ue_sync, srslte_rf_set_rx_gain_th_wrapper_, cell_detect_config.init_agc);
|
||||
srslte_rf_info_t *rf_info = srslte_rf_get_info(&rf);
|
||||
srslte_ue_sync_start_agc(&ue_sync,
|
||||
srslte_rf_set_rx_gain_th_wrapper_,
|
||||
rf_info->min_rx_gain,
|
||||
rf_info->max_rx_gain,
|
||||
cell_detect_config.init_agc);
|
||||
}
|
||||
#endif
|
||||
#ifdef PRINT_CHANGE_SCHEDULIGN
|
||||
|
@ -668,7 +682,7 @@ int main(int argc, char **argv) {
|
|||
decode_pdsch = true;
|
||||
} else {
|
||||
/* We are looking for SIB1 Blocks, search only in appropiate places */
|
||||
if ((sfidx == 5 && (sfn%2)==0) || sfidx == 1) {
|
||||
if ((sfidx == 5 && (sfn%2)==0) ||mch_table[sfidx] == 1) {
|
||||
decode_pdsch = true;
|
||||
} else {
|
||||
decode_pdsch = false;
|
||||
|
@ -677,7 +691,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
gettimeofday(&t[1], NULL);
|
||||
if (decode_pdsch) {
|
||||
if(sfidx != 1 || prog_args.mbsfn_area_id < 0){ // Not an MBSFN subframe
|
||||
if(mch_table[sfidx] == 0 || prog_args.mbsfn_area_id < 0){ // Not an MBSFN subframe
|
||||
if (cell.nof_ports == 1) {
|
||||
/* Transmission mode 1 */
|
||||
n = srslte_ue_dl_decode(&ue_dl, data, 0, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync), acks);
|
||||
|
@ -864,6 +878,8 @@ int main(int argc, char **argv) {
|
|||
PRINT_LINE_ADVANCE_CURSOR();
|
||||
ue_dl.pdsch_pkt_errors = 0;
|
||||
ue_dl.pdsch_pkts_total = 0;
|
||||
ue_dl.pmch_pkt_errors = 0;
|
||||
ue_dl.pmch_pkts_total = 0;
|
||||
/*
|
||||
ue_dl.pkt_errors = 0;
|
||||
ue_dl.pkts_total = 0;
|
||||
|
@ -944,7 +960,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
|
||||
plot_real_t p_sync, pce;
|
||||
plot_scatter_t pscatequal, pscatequal_pdcch;
|
||||
plot_scatter_t pscatequal, pscatequal_pdcch, pscatequal_pmch;
|
||||
|
||||
float tmp_plot[110*15*2048];
|
||||
float tmp_plot2[110*15*2048];
|
||||
|
@ -963,6 +979,15 @@ void *plot_thread_run(void *arg) {
|
|||
plot_scatter_setYAxisScale(&pscatequal, -4, 4);
|
||||
|
||||
plot_scatter_addToWindowGrid(&pscatequal, (char*)"pdsch_ue", 0, 0);
|
||||
|
||||
|
||||
|
||||
plot_scatter_init(&pscatequal_pmch);
|
||||
plot_scatter_setTitle(&pscatequal_pmch, "PMCH - Equalized Symbols");
|
||||
plot_scatter_setXAxisScale(&pscatequal_pmch, -4, 4);
|
||||
plot_scatter_setYAxisScale(&pscatequal_pmch, -4, 4);
|
||||
|
||||
plot_scatter_addToWindowGrid(&pscatequal_pmch, (char*)"pdsch_ue", 0, 1);
|
||||
|
||||
if (!prog_args.disable_plots_except_constellation) {
|
||||
plot_real_init(&pce);
|
||||
|
@ -979,7 +1004,7 @@ void *plot_thread_run(void *arg) {
|
|||
plot_scatter_setXAxisScale(&pscatequal_pdcch, -4, 4);
|
||||
plot_scatter_setYAxisScale(&pscatequal_pdcch, -4, 4);
|
||||
|
||||
plot_real_addToWindowGrid(&pce, (char*)"pdsch_ue", 0, 1);
|
||||
plot_real_addToWindowGrid(&pce, (char*)"pdsch_ue", 0, 2);
|
||||
plot_real_addToWindowGrid(&pscatequal_pdcch, (char*)"pdsch_ue", 1, 0);
|
||||
plot_real_addToWindowGrid(&p_sync, (char*)"pdsch_ue", 1, 1);
|
||||
}
|
||||
|
@ -988,6 +1013,7 @@ void *plot_thread_run(void *arg) {
|
|||
sem_wait(&plot_sem);
|
||||
|
||||
uint32_t nof_symbols = ue_dl.pdsch_cfg.nbits[0].nof_re;
|
||||
uint32_t nof_symbols_pmch = ue_dl.pmch_cfg.nbits[0].nof_re;
|
||||
if (!prog_args.disable_plots_except_constellation) {
|
||||
for (i = 0; i < nof_re; i++) {
|
||||
tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[i]));
|
||||
|
@ -1031,6 +1057,7 @@ void *plot_thread_run(void *arg) {
|
|||
|
||||
plot_scatter_setNewData(&pscatequal, ue_dl.pdsch.d[0], nof_symbols);
|
||||
|
||||
plot_scatter_setNewData(&pscatequal_pmch, ue_dl.pmch.d, nof_symbols_pmch);
|
||||
if (plot_sf_idx == 1) {
|
||||
if (prog_args.net_port_signal > 0) {
|
||||
srslte_netsink_write(&net_sink_signal, &sf_buffer[srslte_ue_sync_sf_len(&ue_sync)/7],
|
||||
|
|
|
@ -113,7 +113,7 @@ int main(int argc, char **argv) {
|
|||
uint32_t m0, m1;
|
||||
float m0_value, m1_value;
|
||||
uint32_t N_id_2;
|
||||
uint32_t sss_idx;
|
||||
int sss_idx;
|
||||
struct timeval tdata[3];
|
||||
int *exec_time;
|
||||
|
||||
|
|
|
@ -51,9 +51,11 @@
|
|||
|
||||
// FIXME: This was chosen arbitrarily
|
||||
#define LIBLTE_ASN1_OID_MAXSUBIDS 128
|
||||
|
||||
// Caution these values must match SRSLTE_ ones in common.h
|
||||
#define LIBLTE_MAX_MSG_SIZE_BITS 102048
|
||||
#define LIBLTE_MAX_MSG_SIZE_BYTES 12756
|
||||
#define LIBLTE_MSG_HEADER_OFFSET 1024
|
||||
#define LIBLTE_MSG_HEADER_OFFSET 1020
|
||||
|
||||
/*******************************************************************************
|
||||
TYPEDEFS
|
||||
|
@ -82,6 +84,8 @@ static const char liblte_error_text[LIBLTE_ERROR_N_ITEMS][64] = {
|
|||
"Decode failure",
|
||||
};
|
||||
|
||||
#define LIBLTE_STRING_LEN 128
|
||||
|
||||
typedef void* LIBLTE_ASN1_OPEN_TYPE_STRUCT;
|
||||
|
||||
typedef struct {
|
||||
|
@ -96,86 +100,15 @@ typedef struct{
|
|||
|
||||
typedef struct{
|
||||
uint32 N_bits;
|
||||
uint8 header[LIBLTE_MSG_HEADER_OFFSET];
|
||||
uint8 msg[LIBLTE_MAX_MSG_SIZE_BITS];
|
||||
}LIBLTE_SIMPLE_BIT_MSG_STRUCT;
|
||||
}LIBLTE_BIT_MSG_STRUCT;
|
||||
|
||||
typedef struct{
|
||||
uint32 N_bytes;
|
||||
uint8 header[LIBLTE_MSG_HEADER_OFFSET];
|
||||
uint8 msg[LIBLTE_MAX_MSG_SIZE_BYTES];
|
||||
}LIBLTE_SIMPLE_BYTE_MSG_STRUCT;
|
||||
|
||||
|
||||
struct LIBLTE_BYTE_MSG_STRUCT{
|
||||
uint32 N_bytes;
|
||||
uint8 buffer[LIBLTE_MAX_MSG_SIZE_BYTES];
|
||||
uint8 *msg;
|
||||
|
||||
LIBLTE_BYTE_MSG_STRUCT():N_bytes(0)
|
||||
{
|
||||
msg = &buffer[LIBLTE_MSG_HEADER_OFFSET];
|
||||
}
|
||||
LIBLTE_BYTE_MSG_STRUCT(const LIBLTE_BYTE_MSG_STRUCT& buf)
|
||||
{
|
||||
N_bytes = buf.N_bytes;
|
||||
memcpy(msg, buf.msg, N_bytes);
|
||||
}
|
||||
LIBLTE_BYTE_MSG_STRUCT & operator= (const LIBLTE_BYTE_MSG_STRUCT & buf)
|
||||
{
|
||||
// avoid self assignment
|
||||
if (&buf == this)
|
||||
return *this;
|
||||
N_bytes = buf.N_bytes;
|
||||
memcpy(msg, buf.msg, N_bytes);
|
||||
return *this;
|
||||
}
|
||||
uint32 get_headroom()
|
||||
{
|
||||
return msg-buffer;
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
N_bytes = 0;
|
||||
msg = &buffer[LIBLTE_MSG_HEADER_OFFSET];
|
||||
}
|
||||
};
|
||||
|
||||
struct LIBLTE_BIT_MSG_STRUCT{
|
||||
uint32 N_bits;
|
||||
uint8 buffer[LIBLTE_MAX_MSG_SIZE_BITS];
|
||||
uint8 *msg;
|
||||
|
||||
LIBLTE_BIT_MSG_STRUCT():N_bits(0)
|
||||
{
|
||||
msg = &buffer[LIBLTE_MSG_HEADER_OFFSET];
|
||||
while( (uint64_t)(msg) % 8 > 0) {
|
||||
msg++;
|
||||
}
|
||||
}
|
||||
LIBLTE_BIT_MSG_STRUCT(const LIBLTE_BIT_MSG_STRUCT& buf){
|
||||
N_bits = buf.N_bits;
|
||||
memcpy(msg, buf.msg, N_bits);
|
||||
}
|
||||
LIBLTE_BIT_MSG_STRUCT & operator= (const LIBLTE_BIT_MSG_STRUCT & buf){
|
||||
// avoid self assignment
|
||||
if (&buf == this)
|
||||
return *this;
|
||||
N_bits = buf.N_bits;
|
||||
memcpy(msg, buf.msg, N_bits);
|
||||
return *this;
|
||||
}
|
||||
uint32 get_headroom()
|
||||
{
|
||||
return msg-buffer;
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
N_bits = 0;
|
||||
msg = &buffer[LIBLTE_MSG_HEADER_OFFSET];
|
||||
while( (uint64_t)(msg) % 8 > 0) {
|
||||
msg++;
|
||||
}
|
||||
}
|
||||
};
|
||||
}LIBLTE_BYTE_MSG_STRUCT;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
@ -1209,7 +1209,7 @@ static const char liblte_mme_add_ci_text[LIBLTE_MME_ADD_CI_N_ITEMS][20] = {"Don'
|
|||
"Add"};
|
||||
// Structs
|
||||
typedef struct{
|
||||
std::string name;
|
||||
char name[LIBLTE_STRING_LEN];
|
||||
LIBLTE_MME_ADD_CI_ENUM add_ci;
|
||||
}LIBLTE_MME_NETWORK_NAME_STRUCT;
|
||||
// Functions
|
||||
|
@ -1752,7 +1752,7 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_guti_type_ie(uint8 **ie_
|
|||
// Enums
|
||||
// Structs
|
||||
typedef struct{
|
||||
std::string apn;
|
||||
char apn[LIBLTE_STRING_LEN];
|
||||
}LIBLTE_MME_ACCESS_POINT_NAME_STRUCT;
|
||||
// Functions
|
||||
LIBLTE_ERROR_ENUM liblte_mme_pack_access_point_name_ie(LIBLTE_MME_ACCESS_POINT_NAME_STRUCT *apn,
|
||||
|
@ -2810,6 +2810,7 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_authentication_request_msg(LIBLTE_BYTE_MSG_S
|
|||
// Structs
|
||||
typedef struct{
|
||||
uint8 res[16];
|
||||
int res_len;
|
||||
}LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT;
|
||||
// Functions
|
||||
LIBLTE_ERROR_ENUM liblte_mme_pack_authentication_response_msg(LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT *auth_resp,
|
||||
|
@ -3791,6 +3792,8 @@ typedef struct{
|
|||
}LIBLTE_MME_ESM_INFORMATION_RESPONSE_MSG_STRUCT;
|
||||
// Functions
|
||||
LIBLTE_ERROR_ENUM liblte_mme_pack_esm_information_response_msg(LIBLTE_MME_ESM_INFORMATION_RESPONSE_MSG_STRUCT *esm_info_resp,
|
||||
uint8 sec_hdr_type,
|
||||
uint32 count,
|
||||
LIBLTE_BYTE_MSG_STRUCT *msg);
|
||||
LIBLTE_ERROR_ENUM liblte_mme_unpack_esm_information_response_msg(LIBLTE_BYTE_MSG_STRUCT *msg,
|
||||
LIBLTE_MME_ESM_INFORMATION_RESPONSE_MSG_STRUCT *esm_info_resp);
|
||||
|
|
|
@ -213,17 +213,111 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_mbsfn_subframe_config_ie(uint8
|
|||
LIBLTE_RRC_MBSFN_SUBFRAME_CONFIG_STRUCT *mbsfn_subfr_cnfg);
|
||||
|
||||
/*********************************************************************
|
||||
IE Name: PMCH Info List
|
||||
IE Name: TMGI
|
||||
|
||||
Description: Specifies configuration of all PMCHs of an MBSFN area
|
||||
Description: Temporary Mobile Group Identity (PLMN + MBMS service ID)
|
||||
|
||||
Document Reference: 36.331 v10.0.0 Section 6.3.7
|
||||
*********************************************************************/
|
||||
// Defines
|
||||
// Enums
|
||||
// Structs
|
||||
typedef struct{
|
||||
uint16 mcc;
|
||||
uint16 mnc;
|
||||
}LIBLTE_RRC_PLMN_IDENTITY_STRUCT;
|
||||
typedef struct{
|
||||
LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id_r9;
|
||||
uint8 plmn_index_r9;
|
||||
bool plmn_id_explicit;
|
||||
uint32 serviceid_r9;
|
||||
}LIBLTE_RRC_TMGI_R9_STRUCT;
|
||||
// Functions
|
||||
// FIXME
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_pack_tmgi_r9_ie(LIBLTE_RRC_TMGI_R9_STRUCT *tmgi,
|
||||
uint8 **ie_ptr);
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_unpack_tmgi_r9_ie(uint8 **ie_ptr,
|
||||
LIBLTE_RRC_TMGI_R9_STRUCT *tmgi);
|
||||
|
||||
/*********************************************************************
|
||||
IE Name: MBMS Session Info
|
||||
|
||||
Description: Information about an individual MBMS session
|
||||
|
||||
Document Reference: 36.331 v10.0.0 Section 6.3.7
|
||||
*********************************************************************/
|
||||
// Defines
|
||||
// Enums
|
||||
// Structs
|
||||
typedef struct{
|
||||
LIBLTE_RRC_TMGI_R9_STRUCT tmgi_r9;
|
||||
uint8 sessionid_r9;
|
||||
bool sessionid_r9_present;
|
||||
uint8 logicalchannelid_r9;
|
||||
}LIBLTE_RRC_MBMS_SESSION_INFO_R9_STRUCT;
|
||||
// Functions
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_pack_mbms_session_info_r9_ie(LIBLTE_RRC_MBMS_SESSION_INFO_R9_STRUCT *mbms_session_info,
|
||||
uint8 **ie_ptr);
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_unpack_mbms_session_info_r9_ie(uint8 **ie_ptr,
|
||||
LIBLTE_RRC_MBMS_SESSION_INFO_R9_STRUCT *mbms_session_info);
|
||||
|
||||
/*********************************************************************
|
||||
IE Name: PMCH Config
|
||||
|
||||
Description: Contains configuration parameters of the sessions
|
||||
carried by a PMCH
|
||||
|
||||
Document Reference: 36.331 v10.0.0 Section 6.3.7
|
||||
*********************************************************************/
|
||||
// Defines
|
||||
|
||||
// Enums
|
||||
typedef enum{
|
||||
LIBLTE_RRC_MCH_SCHEDULING_PERIOD_R9_RF8 = 0,
|
||||
LIBLTE_RRC_MCH_SCHEDULING_PERIOD_R9_RF16,
|
||||
LIBLTE_RRC_MCH_SCHEDULING_PERIOD_R9_RF32,
|
||||
LIBLTE_RRC_MCH_SCHEDULING_PERIOD_R9_RF64,
|
||||
LIBLTE_RRC_MCH_SCHEDULING_PERIOD_R9_RF128,
|
||||
LIBLTE_RRC_MCH_SCHEDULING_PERIOD_R9_RF256,
|
||||
LIBLTE_RRC_MCH_SCHEDULING_PERIOD_R9_RF512,
|
||||
LIBLTE_RRC_MCH_SCHEDULING_PERIOD_R9_RF1024,
|
||||
LIBLTE_RRC_MCH_SCHEDULING_PERIOD_R9_N_ITEMS,
|
||||
}LIBLTE_RRC_MCH_SCHEDULING_PERIOD_R9_ENUM;
|
||||
static const char liblte_rrc_mch_scheduling_period_r9_text[LIBLTE_RRC_MCH_SCHEDULING_PERIOD_R9_N_ITEMS][20] = {"8", "16", "32", "64", "128", "256", "512", "1024"};
|
||||
static const uint16 liblte_rrc_mch_scheduling_period_r9_num[LIBLTE_RRC_MCH_SCHEDULING_PERIOD_R9_N_ITEMS] = {8, 16, 32, 64, 128, 256, 512, 1024};
|
||||
|
||||
// Structs
|
||||
typedef struct{
|
||||
uint16 sf_alloc_end_r9;
|
||||
uint8 datamcs_r9;
|
||||
LIBLTE_RRC_MCH_SCHEDULING_PERIOD_R9_ENUM mch_schedulingperiod_r9;
|
||||
}LIBLTE_RRC_PMCH_CONFIG_R9_STRUCT;
|
||||
// Functions
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_pack_pmch_config_r9_ie(LIBLTE_RRC_PMCH_CONFIG_R9_STRUCT *pmch_cnfg,
|
||||
uint8 **ie_ptr);
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_unpack_pmch_config_r9_ie(uint8 **ie_ptr,
|
||||
LIBLTE_RRC_PMCH_CONFIG_R9_STRUCT *pmch_cnfg);
|
||||
|
||||
/*********************************************************************
|
||||
IE Name: PMCH Info
|
||||
|
||||
Description: Specifies configuration of PMCH of an MBSFN area
|
||||
|
||||
Document Reference: 36.331 v10.0.0 Section 6.3.7
|
||||
*********************************************************************/
|
||||
// Defines
|
||||
#define LIBLTE_RRC_MAX_SESSION_PER_PMCH 29
|
||||
// Enums
|
||||
// Structs
|
||||
typedef struct{
|
||||
LIBLTE_RRC_PMCH_CONFIG_R9_STRUCT pmch_config_r9;
|
||||
LIBLTE_RRC_MBMS_SESSION_INFO_R9_STRUCT mbms_sessioninfolist_r9[LIBLTE_RRC_MAX_SESSION_PER_PMCH];
|
||||
uint8 mbms_sessioninfolist_r9_size;
|
||||
}LIBLTE_RRC_PMCH_INFO_R9_STRUCT;
|
||||
// Functions
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_pack_pmch_info_r9_ie(LIBLTE_RRC_PMCH_INFO_R9_STRUCT *pmch_info,
|
||||
uint8 **ie_ptr);
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_unpack_pmch_info_r9_ie(uint8 **ie_ptr,
|
||||
LIBLTE_RRC_PMCH_INFO_R9_STRUCT *pmch_info);
|
||||
|
||||
/*********************************************************************
|
||||
IE Name: C-RNTI
|
||||
|
@ -2227,10 +2321,6 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_csfb_registration_param_1xrtt_v920_ie(uint8
|
|||
// Defines
|
||||
// Enums
|
||||
// Structs
|
||||
typedef struct{
|
||||
uint16 mcc;
|
||||
uint16 mnc;
|
||||
}LIBLTE_RRC_PLMN_IDENTITY_STRUCT;
|
||||
typedef struct{
|
||||
LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id;
|
||||
uint32 cell_id;
|
||||
|
@ -5135,7 +5225,7 @@ typedef struct{
|
|||
LIBLTE_RRC_UE_TIMERS_AND_CONSTANTS_STRUCT ue_timers_and_constants;
|
||||
LIBLTE_RRC_ARFCN_VALUE_EUTRA_STRUCT arfcn_value_eutra;
|
||||
LIBLTE_RRC_UL_BW_STRUCT ul_bw;
|
||||
LIBLTE_RRC_MBSFN_SUBFRAME_CONFIG_STRUCT mbsfn_subfr_cnfg[LIBLTE_RRC_MAX_MBSFN_ALLOCATIONS];
|
||||
LIBLTE_RRC_MBSFN_SUBFRAME_CONFIG_STRUCT mbsfn_subfr_cnfg_list[LIBLTE_RRC_MAX_MBSFN_ALLOCATIONS];
|
||||
LIBLTE_RRC_TIME_ALIGNMENT_TIMER_ENUM time_alignment_timer;
|
||||
uint32 mbsfn_subfr_cnfg_list_size;
|
||||
uint8 additional_spectrum_emission;
|
||||
|
@ -5545,7 +5635,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_sys_info_block_type_9_ie(uint8
|
|||
// Structs
|
||||
typedef struct{
|
||||
LIBLTE_RRC_MBSFN_AREA_INFO_STRUCT mbsfn_area_info_list_r9[LIBLTE_RRC_MAX_MBSFN_AREAS];
|
||||
LIBLTE_RRC_MBSFN_NOTIFICATION_CONFIG_STRUCT mbms_notification_config;
|
||||
LIBLTE_RRC_MBSFN_NOTIFICATION_CONFIG_STRUCT mbsfn_notification_config;
|
||||
uint8 mbsfn_area_info_list_r9_size;
|
||||
}LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13_STRUCT;
|
||||
// Functions
|
||||
|
@ -5579,7 +5669,7 @@ static const char liblte_rrc_ul_information_transfer_type_text[LIBLTE_RRC_UL_INF
|
|||
"CDMA2000-HRPD"};
|
||||
// Structs
|
||||
typedef struct{
|
||||
LIBLTE_SIMPLE_BYTE_MSG_STRUCT dedicated_info;
|
||||
LIBLTE_BYTE_MSG_STRUCT dedicated_info;
|
||||
LIBLTE_RRC_UL_INFORMATION_TRANSFER_TYPE_ENUM dedicated_info_type;
|
||||
}LIBLTE_RRC_UL_INFORMATION_TRANSFER_STRUCT;
|
||||
// Functions
|
||||
|
@ -5771,18 +5861,18 @@ typedef enum{
|
|||
LIBLTE_RRC_SIB_TYPE_11,
|
||||
LIBLTE_RRC_SIB_TYPE_12_v920,
|
||||
LIBLTE_RRC_SIB_TYPE_13_v920,
|
||||
LIBLTE_RRC_SIB_TYPE_SPARE_5,
|
||||
LIBLTE_RRC_SIB_TYPE_SPARE_4,
|
||||
LIBLTE_RRC_SIB_TYPE_SPARE_3,
|
||||
LIBLTE_RRC_SIB_TYPE_SPARE_2,
|
||||
LIBLTE_RRC_SIB_TYPE_SPARE_1,
|
||||
LIBLTE_RRC_SIB_TYPE_14_v1130,
|
||||
LIBLTE_RRC_SIB_TYPE_15_v1130,
|
||||
LIBLTE_RRC_SIB_TYPE_16_v1130,
|
||||
LIBLTE_RRC_SIB_TYPE_17_v1250,
|
||||
LIBLTE_RRC_SIB_TYPE_18_v1250,
|
||||
LIBLTE_RRC_SIB_TYPE_N_ITEMS,
|
||||
}LIBLTE_RRC_SIB_TYPE_ENUM;
|
||||
static const char liblte_rrc_sib_type_text[LIBLTE_RRC_SIB_TYPE_N_ITEMS][20] = { "3", "4", "5", "6",
|
||||
"7", "8", "9", "10",
|
||||
"11", "12", "13", "SPARE",
|
||||
"SPARE", "SPARE", "SPARE", "SPARE"};
|
||||
static const uint8 liblte_rrc_sib_type_num[LIBLTE_RRC_SIB_TYPE_N_ITEMS] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0};
|
||||
static const char liblte_rrc_sib_type_text[LIBLTE_RRC_SIB_TYPE_N_ITEMS][20] = { "3", "4", "5", "6",
|
||||
"7", "8", "9", "10",
|
||||
"11", "12_v920", "13_v920", "14_v1130",
|
||||
"15_v1130", "16_v1130", "17_v1250", "18_v1250"};
|
||||
static const uint8 liblte_rrc_sib_type_num[LIBLTE_RRC_SIB_TYPE_N_ITEMS] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};
|
||||
// Structs
|
||||
typedef struct{
|
||||
LIBLTE_RRC_PLMN_IDENTITY_STRUCT id;
|
||||
|
@ -5846,14 +5936,20 @@ typedef enum{
|
|||
LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_11,
|
||||
LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_12,
|
||||
LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13,
|
||||
LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_14,
|
||||
LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_15,
|
||||
LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_16,
|
||||
LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_17,
|
||||
LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_18,
|
||||
LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1, // Intentionally not first
|
||||
LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_N_ITEMS,
|
||||
}LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_ENUM;
|
||||
static const char liblte_rrc_sys_info_block_type_text[LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_N_ITEMS][20] = { "2", "3", "4", "5",
|
||||
"6", "7", "8", "9",
|
||||
"10", "11", "12", "13",
|
||||
"1"};
|
||||
static const uint8 liblte_rrc_sys_info_block_type_num[LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_N_ITEMS] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1};
|
||||
"10", "11", "12", "13",
|
||||
"14", "15", "16", "17",
|
||||
"18", "1"};
|
||||
static const uint8 liblte_rrc_sys_info_block_type_num[LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_N_ITEMS] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 1};
|
||||
// Structs
|
||||
typedef union{
|
||||
LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT sib1;
|
||||
|
@ -5960,7 +6056,7 @@ typedef struct{
|
|||
}LIBLTE_RRC_REGISTERED_MME_STRUCT;
|
||||
typedef struct{
|
||||
LIBLTE_RRC_REGISTERED_MME_STRUCT registered_mme;
|
||||
LIBLTE_SIMPLE_BYTE_MSG_STRUCT dedicated_info_nas;
|
||||
LIBLTE_BYTE_MSG_STRUCT dedicated_info_nas;
|
||||
uint8 rrc_transaction_id;
|
||||
uint8 selected_plmn_id;
|
||||
bool registered_mme_present;
|
||||
|
@ -6245,7 +6341,7 @@ typedef struct{
|
|||
typedef struct{
|
||||
LIBLTE_RRC_MEAS_CONFIG_STRUCT meas_cnfg;
|
||||
LIBLTE_RRC_MOBILITY_CONTROL_INFO_STRUCT mob_ctrl_info;
|
||||
LIBLTE_SIMPLE_BYTE_MSG_STRUCT ded_info_nas_list[LIBLTE_RRC_MAX_DRB];
|
||||
LIBLTE_BYTE_MSG_STRUCT ded_info_nas_list[LIBLTE_RRC_MAX_DRB];
|
||||
LIBLTE_RRC_RR_CONFIG_DEDICATED_STRUCT rr_cnfg_ded;
|
||||
LIBLTE_RRC_SECURITY_CONFIG_HO_STRUCT sec_cnfg_ho;
|
||||
uint32 N_ded_info_nas;
|
||||
|
@ -6551,10 +6647,37 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_measurement_report_msg(LIBLTE_BIT_MSG_STRUCT
|
|||
Document Reference: 36.331 v10.0.0 Section 6.2.2
|
||||
*********************************************************************/
|
||||
// Defines
|
||||
#define LIBLTE_RRC_MAX_PMCH_PER_MBSFN 15
|
||||
|
||||
// Enums
|
||||
typedef enum{
|
||||
LIBLTE_RRC_MBSFN_COMMON_SF_ALLOC_PERIOD_R9_RF4 = 0,
|
||||
LIBLTE_RRC_MBSFN_COMMON_SF_ALLOC_PERIOD_R9_RF8,
|
||||
LIBLTE_RRC_MBSFN_COMMON_SF_ALLOC_PERIOD_R9_RF16,
|
||||
LIBLTE_RRC_MBSFN_COMMON_SF_ALLOC_PERIOD_R9_RF32,
|
||||
LIBLTE_RRC_MBSFN_COMMON_SF_ALLOC_PERIOD_R9_RF64,
|
||||
LIBLTE_RRC_MBSFN_COMMON_SF_ALLOC_PERIOD_R9_RF128,
|
||||
LIBLTE_RRC_MBSFN_COMMON_SF_ALLOC_PERIOD_R9_RF256,
|
||||
LIBLTE_RRC_MBSFN_COMMON_SF_ALLOC_PERIOD_R9_N_ITEMS,
|
||||
}LIBLTE_RRC_MBSFN_COMMON_SF_ALLOC_PERIOD_R9_ENUM;
|
||||
static const char liblte_rrc_mbsfn_common_sf_alloc_period_r9_text[LIBLTE_RRC_MBSFN_COMMON_SF_ALLOC_PERIOD_R9_N_ITEMS][20] = {"4", "8", "16", "32",
|
||||
"64", "128", "256"};
|
||||
static const uint32 liblte_rrc_mbsfn_common_sf_alloc_period_r9_num[LIBLTE_RRC_MBSFN_COMMON_SF_ALLOC_PERIOD_R9_N_ITEMS] = {4, 8, 16, 32,
|
||||
64, 128, 256};
|
||||
// Structs
|
||||
typedef struct{
|
||||
LIBLTE_RRC_MBSFN_SUBFRAME_CONFIG_STRUCT commonsf_allocpatternlist_r9[LIBLTE_RRC_MAX_MBSFN_ALLOCATIONS];
|
||||
uint8 commonsf_allocpatternlist_r9_size;
|
||||
LIBLTE_RRC_MBSFN_COMMON_SF_ALLOC_PERIOD_R9_ENUM commonsf_allocperiod_r9;
|
||||
LIBLTE_RRC_PMCH_INFO_R9_STRUCT pmch_infolist_r9[LIBLTE_RRC_MAX_PMCH_PER_MBSFN];
|
||||
uint8 pmch_infolist_r9_size;
|
||||
}LIBLTE_RRC_MBSFN_AREA_CONFIGURATION_R9_STRUCT;
|
||||
|
||||
// Functions
|
||||
// FIXME
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_pack_mbsfn_area_configuration_r9_msg(LIBLTE_RRC_MBSFN_AREA_CONFIGURATION_R9_STRUCT *mbsfn_area_cnfg,
|
||||
LIBLTE_BIT_MSG_STRUCT *msg);
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_unpack_mbsfn_area_configuration_r9_msg(LIBLTE_RRC_MBSFN_AREA_CONFIGURATION_R9_STRUCT *msg,
|
||||
LIBLTE_RRC_PAGING_STRUCT *mbsfn_area_cnfg);
|
||||
|
||||
/*********************************************************************
|
||||
Message Name: Master Information Block
|
||||
|
@ -6626,7 +6749,7 @@ static const char liblte_rrc_dl_information_transfer_type_text[LIBLTE_RRC_DL_INF
|
|||
"CDMA2000-HRPD"};
|
||||
// Structs
|
||||
typedef struct{
|
||||
LIBLTE_SIMPLE_BYTE_MSG_STRUCT dedicated_info;
|
||||
LIBLTE_BYTE_MSG_STRUCT dedicated_info;
|
||||
LIBLTE_RRC_DL_INFORMATION_TRANSFER_TYPE_ENUM dedicated_info_type;
|
||||
uint8 rrc_transaction_id;
|
||||
}LIBLTE_RRC_DL_INFORMATION_TRANSFER_STRUCT;
|
||||
|
@ -6783,8 +6906,12 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_bcch_dlsch_msg(LIBLTE_BIT_MSG_STRUCT
|
|||
// Defines
|
||||
// Enums
|
||||
// Structs
|
||||
typedef LIBLTE_RRC_MBSFN_AREA_CONFIGURATION_R9_STRUCT LIBLTE_RRC_MCCH_MSG_STRUCT;
|
||||
// Functions
|
||||
// FIXME
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_pack_mcch_msg(LIBLTE_RRC_MCCH_MSG_STRUCT *mcch_msg,
|
||||
LIBLTE_BIT_MSG_STRUCT *msg);
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_unpack_mcch_msg(LIBLTE_BIT_MSG_STRUCT *msg,
|
||||
LIBLTE_RRC_MCCH_MSG_STRUCT *mcch_msg);
|
||||
|
||||
/*********************************************************************
|
||||
Message Name: PCCH Message
|
||||
|
|
|
@ -24,6 +24,15 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* File: block_queue.h
|
||||
* Description: General-purpose blocking queue. It can behave as a bounded or
|
||||
* unbounded blocking queue and allows blocking and non-blocking
|
||||
* operations in both push and pop
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#ifndef SRSLTE_BLOCK_QUEUE_H
|
||||
#define SRSLTE_BLOCK_QUEUE_H
|
||||
|
||||
|
@ -32,21 +41,62 @@
|
|||
#include <utility>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace srslte {
|
||||
|
||||
template<typename myobj>
|
||||
class block_queue {
|
||||
|
||||
public:
|
||||
block_queue<myobj>() {
|
||||
|
||||
// Callback functions for mutexed operations inside pop/push methods
|
||||
class call_mutexed_itf {
|
||||
public:
|
||||
virtual void popping(myobj obj) = 0;
|
||||
virtual void pushing(myobj obj) = 0;
|
||||
};
|
||||
|
||||
block_queue<myobj>(int capacity = -1) {
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
pthread_cond_init(&cvar, NULL);
|
||||
pthread_cond_init(&cv_empty, NULL);
|
||||
pthread_cond_init(&cv_full, NULL);
|
||||
this->capacity = capacity;
|
||||
mutexed_callback = NULL;
|
||||
}
|
||||
void push(const myobj& value) {
|
||||
void set_mutexed_itf(call_mutexed_itf *itf) {
|
||||
mutexed_callback = itf;
|
||||
}
|
||||
void resize(int new_capacity) {
|
||||
capacity = new_capacity;
|
||||
}
|
||||
bool push_(const myobj& value, bool block) {
|
||||
pthread_mutex_lock(&mutex);
|
||||
if (capacity > 0) {
|
||||
if (block) {
|
||||
while(q.size() > (uint32_t) capacity) {
|
||||
pthread_cond_wait(&cv_full, &mutex);
|
||||
}
|
||||
} else {
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
q.push(value);
|
||||
pthread_cond_signal(&cvar);
|
||||
if (mutexed_callback) {
|
||||
mutexed_callback->pushing(value);
|
||||
}
|
||||
pthread_cond_signal(&cv_empty);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
void push(const myobj& value) {
|
||||
push_(value, true);
|
||||
}
|
||||
|
||||
bool try_push(const myobj& value) {
|
||||
return push_(value, false);
|
||||
}
|
||||
|
||||
bool try_pop(myobj *value) {
|
||||
|
@ -59,6 +109,10 @@ public:
|
|||
*value = q.front();
|
||||
q.pop();
|
||||
}
|
||||
if (mutexed_callback) {
|
||||
mutexed_callback->popping(*value);
|
||||
}
|
||||
pthread_cond_signal(&cv_full);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return true;
|
||||
}
|
||||
|
@ -66,15 +120,19 @@ public:
|
|||
myobj wait_pop() { // blocking pop
|
||||
pthread_mutex_lock(&mutex);
|
||||
while(q.empty()) {
|
||||
pthread_cond_wait(&cvar, &mutex);
|
||||
pthread_cond_wait(&cv_empty, &mutex);
|
||||
}
|
||||
myobj value = q.front();
|
||||
q.pop();
|
||||
if (mutexed_callback) {
|
||||
mutexed_callback->popping(value);
|
||||
}
|
||||
pthread_cond_signal(&cv_full);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return value;
|
||||
}
|
||||
|
||||
bool empty() const { // queue is empty?
|
||||
bool empty() { // queue is empty?
|
||||
pthread_mutex_lock(&mutex);
|
||||
bool ret = q.empty();
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
@ -86,10 +144,21 @@ public:
|
|||
while (try_pop(item));
|
||||
}
|
||||
|
||||
myobj front() {
|
||||
return q.front();
|
||||
}
|
||||
|
||||
size_t size() {
|
||||
return q.size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::queue<myobj> q;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cvar;
|
||||
pthread_cond_t cv_empty;
|
||||
pthread_cond_t cv_full;
|
||||
call_mutexed_itf *mutexed_callback;
|
||||
int capacity;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -93,6 +93,10 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
uint32_t nof_available_pdus() {
|
||||
return available.size();
|
||||
}
|
||||
|
||||
bool is_almost_empty() {
|
||||
return available.size() < capacity/20;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
#define SRSLTE_N_DRB 8
|
||||
#define SRSLTE_N_RADIO_BEARERS 11
|
||||
|
||||
#define SRSLTE_N_MCH_LCIDS 32
|
||||
|
||||
#define HARQ_DELAY_MS 4
|
||||
#define MSG3_DELAY_MS 2 // Delay added to HARQ_DELAY_MS
|
||||
#define TTI_RX(tti) (tti>HARQ_DELAY_MS?((tti-HARQ_DELAY_MS)%10240):(10240+tti-HARQ_DELAY_MS))
|
||||
|
@ -61,17 +63,19 @@
|
|||
// 3GPP 36.306 Table 4.1.1
|
||||
#define SRSLTE_MAX_BUFFER_SIZE_BITS 102048
|
||||
#define SRSLTE_MAX_BUFFER_SIZE_BYTES 12756
|
||||
#define SRSLTE_BUFFER_HEADER_OFFSET 1024
|
||||
#define SRSLTE_BUFFER_HEADER_OFFSET 1020
|
||||
|
||||
#define SRSLTE_BUFFER_POOL_LOG_ENABLED
|
||||
|
||||
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
|
||||
#define pool_allocate (pool->allocate(__FUNCTION__))
|
||||
#define pool_allocate (pool->allocate(__PRETTY_FUNCTION__))
|
||||
#define SRSLTE_BUFFER_POOL_LOG_NAME_LEN 128
|
||||
#else
|
||||
#define pool_allocate (pool->allocate())
|
||||
#endif
|
||||
|
||||
#define ZERO_OBJECT(x) memset(&(x), 0x0, sizeof((x)))
|
||||
|
||||
#include "srslte/srslte.h"
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -116,15 +120,17 @@ public:
|
|||
|
||||
byte_buffer_t():N_bytes(0)
|
||||
{
|
||||
timestamp_is_set = false;
|
||||
bzero(buffer, SRSLTE_MAX_BUFFER_SIZE_BYTES);
|
||||
timestamp_is_set = false;
|
||||
msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET];
|
||||
next = NULL;
|
||||
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
|
||||
debug_name[0] = 0;
|
||||
bzero(debug_name, SRSLTE_BUFFER_POOL_LOG_NAME_LEN);
|
||||
#endif
|
||||
}
|
||||
byte_buffer_t(const byte_buffer_t& buf)
|
||||
{
|
||||
bzero(buffer, SRSLTE_MAX_BUFFER_SIZE_BYTES);
|
||||
N_bytes = buf.N_bytes;
|
||||
memcpy(msg, buf.msg, N_bytes);
|
||||
}
|
||||
|
@ -133,6 +139,7 @@ public:
|
|||
// avoid self assignment
|
||||
if (&buf == this)
|
||||
return *this;
|
||||
bzero(buffer, SRSLTE_MAX_BUFFER_SIZE_BYTES);
|
||||
N_bytes = buf.N_bytes;
|
||||
memcpy(msg, buf.msg, N_bytes);
|
||||
return *this;
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsUE library.
|
||||
*
|
||||
* srsUE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsUE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SRSLTE_CONFIG_FILE_H
|
||||
#define SRSLTE_CONFIG_FILE_H
|
||||
|
||||
#include <fstream>
|
||||
#include <pwd.h>
|
||||
#include "common.h"
|
||||
|
||||
bool config_exists(std::string &filename, std::string default_name)
|
||||
{
|
||||
std::ifstream conf(filename.c_str(), std::ios::in);
|
||||
if(conf.fail()) {
|
||||
const char *homedir = NULL;
|
||||
char full_path[256];
|
||||
ZERO_OBJECT(full_path);
|
||||
if ((homedir = getenv("HOME")) == NULL) {
|
||||
homedir = getpwuid(getuid())->pw_dir;
|
||||
}
|
||||
if (!homedir) {
|
||||
homedir = ".";
|
||||
}
|
||||
snprintf(full_path, sizeof(full_path), "%s/.srs/%s", homedir, default_name.c_str());
|
||||
filename = std::string(full_path);
|
||||
|
||||
// try to open again
|
||||
conf.open(filename.c_str());
|
||||
if (conf.fail()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // SRSLTE_CONFIG_FILE_H
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsUE library.
|
||||
*
|
||||
* srsUE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsUE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GEN_MCH_TALBES_H
|
||||
#define GEN_MCH_TALBES_H
|
||||
|
||||
/******************************************************************************
|
||||
* Common mch table generation - used in phch_common of UE and ENB for MBMS
|
||||
*****************************************************************************/
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
void generate_frame_mch_table(uint8_t *table, uint8_t alloc);
|
||||
void generate_mch_table(uint8_t *table, uint32_t sf_alloc, uint8_t num_frames);
|
||||
void generate_mcch_table(uint8_t *table, uint32_t sf_alloc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
#endif // SECURITY_H
|
|
@ -38,13 +38,19 @@ namespace srslte {
|
|||
class srslte_nas_config_t
|
||||
{
|
||||
public:
|
||||
srslte_nas_config_t(uint32_t lcid_ = 0, std::string apn_ = "")
|
||||
srslte_nas_config_t(uint32_t lcid_ = 0, std::string apn_ = "", std::string user_ = "", std::string pass_ = "", bool force_imsi_attach_ = false)
|
||||
:lcid(lcid_),
|
||||
apn(apn_)
|
||||
apn(apn_),
|
||||
user(user_),
|
||||
pass(pass_),
|
||||
force_imsi_attach(force_imsi_attach_)
|
||||
{}
|
||||
|
||||
uint32_t lcid;
|
||||
std::string apn;
|
||||
std::string user;
|
||||
std::string pass;
|
||||
bool force_imsi_attach;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -129,13 +129,13 @@ public:
|
|||
virtual void debug(const char * message, ...) __attribute__ ((format (printf, 2, 3))) = 0;
|
||||
|
||||
// Same with hex dump
|
||||
virtual void error_hex(const uint8_t *hex, int size, const char *, ...) __attribute__((format (printf, 4, 5)))
|
||||
virtual void error_hex(const uint8_t *, int, const char *, ...) __attribute__((format (printf, 4, 5)))
|
||||
{error("error_hex not implemented.\n");}
|
||||
virtual void warning_hex(const uint8_t *hex, int size, const char *, ...) __attribute__((format (printf, 4, 5)))
|
||||
virtual void warning_hex(const uint8_t *, int, const char *, ...) __attribute__((format (printf, 4, 5)))
|
||||
{error("warning_hex not implemented.\n");}
|
||||
virtual void info_hex(const uint8_t *hex, int size, const char *, ...) __attribute__((format (printf, 4, 5)))
|
||||
virtual void info_hex(const uint8_t *, int, const char *, ...) __attribute__((format (printf, 4, 5)))
|
||||
{error("info_hex not implemented.\n");}
|
||||
virtual void debug_hex(const uint8_t *hex, int size, const char *, ...) __attribute__((format (printf, 4, 5)))
|
||||
virtual void debug_hex(const uint8_t *, int, const char *, ...) __attribute__((format (printf, 4, 5)))
|
||||
{error("debug_hex not implemented.\n");}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
void write_dl_sirnti(uint8_t *pdu, uint32_t pdu_len_bytes, bool crc_ok, uint32_t tti);
|
||||
void write_dl_bch(uint8_t *pdu, uint32_t pdu_len_bytes, bool crc_ok, uint32_t tti);
|
||||
void write_dl_pch(uint8_t *pdu, uint32_t pdu_len_bytes, bool crc_ok, uint32_t tti);
|
||||
void write_dl_mch(uint8_t *pdu, uint32_t pdu_len_bytes, bool crc_ok, uint32_t tti);
|
||||
|
||||
private:
|
||||
bool enable_write;
|
||||
|
|
|
@ -63,7 +63,7 @@ private:
|
|||
get_time_interval(sleep_period_start);
|
||||
uint32_t period = sleep_period_start[0].tv_sec*1e6 + sleep_period_start[0].tv_usec;
|
||||
if (m) {
|
||||
metrics_t metric = {};
|
||||
metrics_t metric;
|
||||
m->get_metrics(metric);
|
||||
for (uint32_t i=0;i<listeners.size();i++) {
|
||||
listeners[i]->set_metrics(metric, period);
|
||||
|
|
|
@ -1,155 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsUE library.
|
||||
*
|
||||
* srsUE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsUE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* File: msg_queue.h
|
||||
* Description: Thread-safe bounded circular buffer of srsue_byte_buffer pointers.
|
||||
* Reference:
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef SRSLTE_MSG_QUEUE_H
|
||||
#define SRSLTE_MSG_QUEUE_H
|
||||
|
||||
#include "srslte/common/common.h"
|
||||
#include <pthread.h>
|
||||
|
||||
namespace srslte {
|
||||
|
||||
class msg_queue
|
||||
{
|
||||
public:
|
||||
msg_queue(uint32_t capacity_ = 128)
|
||||
:head(0)
|
||||
,tail(0)
|
||||
,unread(0)
|
||||
,unread_bytes(0)
|
||||
,capacity(capacity_)
|
||||
{
|
||||
buf = new byte_buffer_t*[capacity];
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
pthread_cond_init(¬_empty, NULL);
|
||||
pthread_cond_init(¬_full, NULL);
|
||||
}
|
||||
|
||||
~msg_queue()
|
||||
{
|
||||
pthread_mutex_destroy(&mutex);
|
||||
pthread_cond_destroy(¬_empty);
|
||||
pthread_cond_destroy(¬_full);
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
void write(byte_buffer_t *msg)
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
while(is_full()) {
|
||||
pthread_cond_wait(¬_full, &mutex);
|
||||
}
|
||||
buf[head] = msg;
|
||||
head = (head+1)%capacity;
|
||||
unread++;
|
||||
unread_bytes += msg->N_bytes;
|
||||
|
||||
pthread_cond_signal(¬_empty);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
void read(byte_buffer_t **msg)
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
while(is_empty()) {
|
||||
pthread_cond_wait(¬_empty, &mutex);
|
||||
}
|
||||
*msg = buf[tail];
|
||||
tail = (tail+1)%capacity;
|
||||
unread--;
|
||||
unread_bytes -= (*msg)->N_bytes;
|
||||
|
||||
pthread_cond_signal(¬_full);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
bool try_read(byte_buffer_t **msg)
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
if(is_empty())
|
||||
{
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return false;
|
||||
}else{
|
||||
*msg = buf[tail];
|
||||
tail = (tail+1)%capacity;
|
||||
unread--;
|
||||
unread_bytes -= (*msg)->N_bytes;
|
||||
pthread_cond_signal(¬_full);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t size()
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
uint32_t r = unread;
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32_t size_bytes()
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
uint32_t r = unread_bytes;
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32_t size_tail_bytes()
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
uint32_t r = buf[tail]->N_bytes;
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return r;
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_empty() const { return unread == 0; }
|
||||
bool is_full() const { return unread == capacity; }
|
||||
|
||||
pthread_cond_t not_empty;
|
||||
pthread_cond_t not_full;
|
||||
pthread_mutex_t mutex;
|
||||
byte_buffer_t **buf;
|
||||
uint32_t capacity;
|
||||
uint32_t unread;
|
||||
uint32_t unread_bytes;
|
||||
uint32_t head;
|
||||
uint32_t tail;
|
||||
};
|
||||
|
||||
} // namespace srslte
|
||||
|
||||
|
||||
#endif // SRSLTE_MSG_QUEUE_H
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#define MAC_LTE_DLT 147
|
||||
#define NAS_LTE_DLT 148
|
||||
#define RLC_LTE_DLT 149 // UDP needs to be selected as protocol
|
||||
|
||||
|
||||
/* This structure gets written to the start of the file */
|
||||
|
@ -104,6 +105,67 @@ typedef struct NAS_Context_Info_s {
|
|||
} NAS_Context_Info_t;
|
||||
|
||||
|
||||
/* RLC-LTE disector */
|
||||
|
||||
/* rlcMode */
|
||||
#define RLC_TM_MODE 1
|
||||
#define RLC_UM_MODE 2
|
||||
#define RLC_AM_MODE 4
|
||||
#define RLC_PREDEF 8
|
||||
|
||||
/* priority ? */
|
||||
|
||||
/* channelType */
|
||||
#define CHANNEL_TYPE_CCCH 1
|
||||
#define CHANNEL_TYPE_BCCH_BCH 2
|
||||
#define CHANNEL_TYPE_PCCH 3
|
||||
#define CHANNEL_TYPE_SRB 4
|
||||
#define CHANNEL_TYPE_DRB 5
|
||||
#define CHANNEL_TYPE_BCCH_DL_SCH 6
|
||||
#define CHANNEL_TYPE_MCCH 7
|
||||
#define CHANNEL_TYPE_MTCH 8
|
||||
|
||||
/* sequenceNumberLength */
|
||||
#define UM_SN_LENGTH_5_BITS 5
|
||||
#define UM_SN_LENGTH_10_BITS 10
|
||||
#define AM_SN_LENGTH_10_BITS 10
|
||||
#define AM_SN_LENGTH_16_BITS 16
|
||||
|
||||
/* Narrow band mode */
|
||||
typedef enum {
|
||||
rlc_no_nb_mode = 0,
|
||||
rlc_nb_mode = 1
|
||||
} rlc_lte_nb_mode;
|
||||
|
||||
/* Context information for every RLC PDU that will be logged */
|
||||
typedef struct {
|
||||
unsigned char rlcMode;
|
||||
unsigned char direction;
|
||||
unsigned char priority;
|
||||
unsigned char sequenceNumberLength;
|
||||
unsigned short ueid;
|
||||
unsigned short channelType;
|
||||
unsigned short channelId; /* for SRB: 1=SRB1, 2=SRB2, 3=SRB1bis; for DRB: DRB ID */
|
||||
unsigned short pduLength;
|
||||
bool extendedLiField;
|
||||
rlc_lte_nb_mode nbMode;
|
||||
} RLC_Context_Info_t;
|
||||
|
||||
|
||||
// See Wireshark's packet-rlc-lte.h for details
|
||||
#define RLC_LTE_START_STRING "rlc-lte"
|
||||
#define RLC_LTE_SN_LENGTH_TAG 0x02
|
||||
#define RLC_LTE_DIRECTION_TAG 0x03
|
||||
#define RLC_LTE_PRIORITY_TAG 0x04
|
||||
#define RLC_LTE_UEID_TAG 0x05
|
||||
#define RLC_LTE_CHANNEL_TYPE_TAG 0x06
|
||||
#define RLC_LTE_CHANNEL_ID_TAG 0x07
|
||||
#define RLC_LTE_EXT_LI_FIELD_TAG 0x08
|
||||
#define RLC_LTE_NB_MODE_TAG 0x09
|
||||
#define RLC_LTE_PAYLOAD_TAG 0x01
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* API functions for opening/closing LTE PCAP files *
|
||||
**************************************************************************/
|
||||
|
@ -247,4 +309,93 @@ inline int LTE_PCAP_NAS_WritePDU(FILE *fd, NAS_Context_Info_t *context,
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* API functions for writing RLC-LTE PCAP files *
|
||||
**************************************************************************/
|
||||
|
||||
/* Write an individual RLC PDU (PCAP packet header + UDP header + rlc-context + rlc-pdu) */
|
||||
inline int LTE_PCAP_RLC_WritePDU(FILE *fd, RLC_Context_Info_t *context,
|
||||
const unsigned char *PDU, unsigned int length)
|
||||
{
|
||||
pcaprec_hdr_t packet_header;
|
||||
char context_header[256];
|
||||
int offset = 0;
|
||||
uint16_t tmp16;
|
||||
|
||||
/* Can't write if file wasn't successfully opened */
|
||||
if (fd == NULL) {
|
||||
printf("Error: Can't write to empty file handle\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
// Add dummy UDP header, start with src and dest port
|
||||
context_header[offset++] = 0xde;
|
||||
context_header[offset++] = 0xad;
|
||||
context_header[offset++] = 0xbe;
|
||||
context_header[offset++] = 0xef;
|
||||
// length
|
||||
tmp16 = length + 12;
|
||||
memcpy(context_header+offset, &tmp16, 2);
|
||||
offset += 2;
|
||||
// dummy CRC
|
||||
context_header[offset++] = 0xde;
|
||||
context_header[offset++] = 0xad;
|
||||
|
||||
// Start magic string
|
||||
memcpy(&context_header[offset], RLC_LTE_START_STRING, strlen(RLC_LTE_START_STRING));
|
||||
offset += strlen(RLC_LTE_START_STRING);
|
||||
|
||||
// Fixed field RLC mode
|
||||
context_header[offset++] = context->rlcMode;
|
||||
|
||||
// Conditional fields
|
||||
if (context->rlcMode == RLC_UM_MODE) {
|
||||
context_header[offset++] = RLC_LTE_SN_LENGTH_TAG;
|
||||
context_header[offset++] = context->sequenceNumberLength;
|
||||
}
|
||||
|
||||
// Optional fields
|
||||
context_header[offset++] = RLC_LTE_DIRECTION_TAG;
|
||||
context_header[offset++] = context->direction;
|
||||
|
||||
context_header[offset++] = RLC_LTE_PRIORITY_TAG;
|
||||
context_header[offset++] = context->priority;
|
||||
|
||||
context_header[offset++] = RLC_LTE_UEID_TAG;
|
||||
tmp16 = htons(context->ueid);
|
||||
memcpy(context_header+offset, &tmp16, 2);
|
||||
offset += 2;
|
||||
|
||||
context_header[offset++] = RLC_LTE_CHANNEL_TYPE_TAG;
|
||||
tmp16 = htons(context->channelType);
|
||||
memcpy(context_header+offset, &tmp16, 2);
|
||||
offset += 2;
|
||||
|
||||
context_header[offset++] = RLC_LTE_CHANNEL_ID_TAG;
|
||||
tmp16 = htons(context->channelId);
|
||||
memcpy(context_header+offset, &tmp16, 2);
|
||||
offset += 2;
|
||||
|
||||
// Now the actual PDU
|
||||
context_header[offset++] = RLC_LTE_PAYLOAD_TAG;
|
||||
|
||||
// PCAP header
|
||||
struct timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
packet_header.ts_sec = t.tv_sec;
|
||||
packet_header.ts_usec = t.tv_usec;
|
||||
packet_header.incl_len = offset + length;
|
||||
packet_header.orig_len = offset + length;
|
||||
|
||||
// Write everything to file
|
||||
fwrite(&packet_header, sizeof(pcaprec_hdr_t), 1, fd);
|
||||
fwrite(context_header, 1, offset, fd);
|
||||
fwrite(PDU, 1, length, fd);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // SRSLTE_PCAP_H
|
||||
|
|
|
@ -34,10 +34,10 @@
|
|||
#include <stdio.h>
|
||||
|
||||
/* MAC PDU Packing/Unpacking functions. Section 6 of 36.321 */
|
||||
|
||||
class subh;
|
||||
|
||||
namespace srslte {
|
||||
|
||||
|
||||
template<class SubH>
|
||||
class pdu
|
||||
{
|
||||
|
@ -147,10 +147,11 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
std::vector<SubH> subheaders;
|
||||
uint32_t pdu_len;
|
||||
uint32_t rem_len;
|
||||
uint32_t rem_len;
|
||||
int cur_idx;
|
||||
int nof_subheaders;
|
||||
uint32_t max_subheaders;
|
||||
|
@ -159,11 +160,10 @@ protected:
|
|||
uint32_t total_sdu_len;
|
||||
uint32_t sdu_offset_start;
|
||||
int last_sdu_idx;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
/* Prepares the PDU for parsing or writing by setting the number of subheaders to 0 and the pdu length */
|
||||
void init_(uint8_t *buffer_tx_ptr, uint32_t pdu_len_bytes, bool is_ulsch) {
|
||||
virtual void init_(uint8_t *buffer_tx_ptr, uint32_t pdu_len_bytes, bool is_ulsch) {
|
||||
nof_subheaders = 0;
|
||||
pdu_len = pdu_len_bytes;
|
||||
rem_len = pdu_len;
|
||||
|
@ -180,55 +180,80 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
SCH_SUBH_TYPE = 0,
|
||||
MCH_SUBH_TYPE = 1,
|
||||
RAR_SUBH_TYPE = 2
|
||||
} subh_type;
|
||||
|
||||
template<class SubH>
|
||||
class subh
|
||||
{
|
||||
public:
|
||||
|
||||
public:
|
||||
subh(){}
|
||||
virtual ~subh(){}
|
||||
|
||||
virtual bool read_subheader(uint8_t** ptr) = 0;
|
||||
virtual void read_payload(uint8_t **ptr) = 0;
|
||||
virtual void write_subheader(uint8_t** ptr, bool is_last) = 0;
|
||||
virtual void write_payload(uint8_t **ptr) = 0;
|
||||
virtual void fprint(FILE *stream) = 0;
|
||||
|
||||
|
||||
pdu<SubH>* parent;
|
||||
private:
|
||||
private:
|
||||
virtual void init() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class sch_subh : public subh<sch_subh>
|
||||
{
|
||||
public:
|
||||
sch_subh(subh_type type_ = SCH_SUBH_TYPE) {
|
||||
lcid = 0;
|
||||
nof_bytes = 0;
|
||||
payload = NULL;
|
||||
nof_mch_sched_ce = 0;
|
||||
cur_mch_sched_ce = 0;
|
||||
F_bit = false;
|
||||
type = type_;
|
||||
parent = NULL;
|
||||
bzero(&w_payload_ce, sizeof(w_payload_ce));
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~sch_subh(){}
|
||||
|
||||
typedef enum {
|
||||
PHR_REPORT = 26,
|
||||
CRNTI = 27,
|
||||
CON_RES_ID = 28,
|
||||
TRUNC_BSR = 28,
|
||||
TA_CMD = 29,
|
||||
SHORT_BSR = 29,
|
||||
DRX_CMD = 30,
|
||||
LONG_BSR = 30,
|
||||
PADDING = 31,
|
||||
SDU = 0
|
||||
} cetype;
|
||||
|
||||
PHR_REPORT = 26,
|
||||
CRNTI = 27,
|
||||
CON_RES_ID = 28,
|
||||
MTCH_MAX_LCID = 28,
|
||||
TRUNC_BSR = 28,
|
||||
TA_CMD = 29,
|
||||
SHORT_BSR = 29,
|
||||
DRX_CMD = 30,
|
||||
LONG_BSR = 30,
|
||||
MCH_SCHED_INFO = 30,
|
||||
PADDING = 31,
|
||||
SDU = 0
|
||||
} cetype;
|
||||
|
||||
// Size of MAC CEs
|
||||
const static int MAC_CE_CONTRES_LEN = 6;
|
||||
|
||||
// Reading functions
|
||||
bool is_sdu();
|
||||
cetype ce_type();
|
||||
bool is_var_len_ce();
|
||||
cetype ce_type();
|
||||
uint32_t size_plus_header();
|
||||
void set_payload_size(uint32_t size);
|
||||
|
||||
bool read_subheader(uint8_t** ptr);
|
||||
void read_payload(uint8_t **ptr);
|
||||
|
||||
bool read_subheader(uint8_t** ptr);
|
||||
void read_payload(uint8_t **ptr);
|
||||
|
||||
uint32_t get_sdu_lcid();
|
||||
int get_payload_size();
|
||||
uint32_t get_payload_size();
|
||||
uint32_t get_header_size(bool is_last);
|
||||
uint8_t* get_sdu_ptr();
|
||||
|
||||
|
@ -237,10 +262,13 @@ public:
|
|||
uint8_t get_ta_cmd();
|
||||
float get_phr();
|
||||
int get_bsr(uint32_t buff_size[4]);
|
||||
|
||||
bool get_next_mch_sched_info(uint8_t *lcid, uint16_t *mtch_stop);
|
||||
|
||||
// Writing functions
|
||||
void write_subheader(uint8_t** ptr, bool is_last);
|
||||
void write_payload(uint8_t **ptr);
|
||||
void write_subheader(uint8_t** ptr, bool is_last);
|
||||
void write_payload(uint8_t **ptr);
|
||||
|
||||
int set_sdu(uint32_t lcid, uint32_t nof_bytes, uint8_t *payload);
|
||||
int set_sdu(uint32_t lcid, uint32_t requested_bytes, read_pdu_interface *sdu_itf);
|
||||
bool set_c_rnti(uint16_t crnti);
|
||||
|
@ -251,46 +279,62 @@ public:
|
|||
void set_padding();
|
||||
void set_padding(uint32_t padding_len);
|
||||
|
||||
void init();
|
||||
void fprint(FILE *stream);
|
||||
void init();
|
||||
void fprint(FILE *stream);
|
||||
|
||||
bool set_next_mch_sched_info(uint8_t lcid, uint16_t mtch_stop);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
static const int MAX_CE_PAYLOAD_LEN = 8;
|
||||
uint32_t lcid;
|
||||
int nof_bytes;
|
||||
uint8_t* payload;
|
||||
uint8_t w_payload_ce[64];
|
||||
uint8_t nof_mch_sched_ce;
|
||||
uint8_t cur_mch_sched_ce;
|
||||
bool F_bit;
|
||||
subh_type type;
|
||||
|
||||
private:
|
||||
static const int MAX_CE_PAYLOAD_LEN = 8;
|
||||
uint32_t lcid;
|
||||
int nof_bytes;
|
||||
uint8_t* payload;
|
||||
uint8_t w_payload_ce[8];
|
||||
bool F_bit;
|
||||
uint32_t sizeof_ce(uint32_t lcid, bool is_ul);
|
||||
static uint8_t buff_size_table(uint32_t buffer_size);
|
||||
static uint8_t phr_report_table(float phr_value);
|
||||
};
|
||||
|
||||
|
||||
class sch_pdu : public pdu<sch_subh>
|
||||
{
|
||||
public:
|
||||
sch_pdu(uint32_t max_subh): pdu(max_subh) {}
|
||||
|
||||
sch_pdu(uint32_t max_subh) : pdu(max_subh) {}
|
||||
|
||||
void parse_packet(uint8_t *ptr);
|
||||
uint8_t* write_packet();
|
||||
uint8_t* write_packet(srslte::log *log_h);
|
||||
bool has_space_ce(uint32_t nbytes);
|
||||
bool has_space_ce(uint32_t nbytes, bool var_len=false);
|
||||
bool has_space_sdu(uint32_t nbytes);
|
||||
int get_pdu_len();
|
||||
int rem_size();
|
||||
int get_sdu_space();
|
||||
|
||||
static uint32_t size_header_sdu(uint32_t nbytes);
|
||||
bool update_space_ce(uint32_t nbytes);
|
||||
bool update_space_sdu(uint32_t nbytes);
|
||||
bool update_space_ce(uint32_t nbytes, bool var_len=false);
|
||||
bool update_space_sdu(uint32_t nbytes);
|
||||
void fprint(FILE *stream);
|
||||
|
||||
};
|
||||
|
||||
class rar_subh : public subh<rar_subh>
|
||||
{
|
||||
public:
|
||||
rar_subh() {
|
||||
bzero(&grant, sizeof(grant));
|
||||
ta = 0;
|
||||
temp_rnti = 0;
|
||||
preamble = 0;
|
||||
parent = NULL;
|
||||
}
|
||||
|
||||
static const uint32_t RAR_GRANT_LEN = 20;
|
||||
|
||||
|
@ -333,11 +377,50 @@ public:
|
|||
bool write_packet(uint8_t* ptr);
|
||||
void fprint(FILE *stream);
|
||||
|
||||
private:
|
||||
private:
|
||||
bool has_backoff_indicator;
|
||||
uint8_t backoff_indicator;
|
||||
|
||||
};
|
||||
|
||||
} // namespace srslte
|
||||
class mch_subh : public sch_subh
|
||||
{
|
||||
public:
|
||||
mch_subh():sch_subh(MCH_SUBH_TYPE){}
|
||||
|
||||
// Size of MAC CEs
|
||||
const static int MAC_CE_CONTRES_LEN = 6;
|
||||
};
|
||||
|
||||
class mch_pdu : public sch_pdu
|
||||
{
|
||||
public:
|
||||
mch_pdu(uint32_t max_subh) : sch_pdu(max_subh) {}
|
||||
|
||||
private:
|
||||
|
||||
/* Prepares the PDU for parsing or writing by setting the number of subheaders to 0 and the pdu length */
|
||||
virtual void init_(uint8_t *buffer_tx_ptr, uint32_t pdu_len_bytes, bool is_ulsch) {
|
||||
nof_subheaders = 0;
|
||||
pdu_len = pdu_len_bytes;
|
||||
rem_len = pdu_len;
|
||||
pdu_is_ul = is_ulsch;
|
||||
buffer_tx = buffer_tx_ptr;
|
||||
sdu_offset_start = max_subheaders*2 + 13; // Assuming worst-case 2 bytes per sdu subheader + all possible CE
|
||||
total_sdu_len = 0;
|
||||
last_sdu_idx = -1;
|
||||
reset();
|
||||
for (uint32_t i=0;i<max_subheaders;i++) {
|
||||
mch_subh mch_subh1;
|
||||
subheaders[i] = mch_subh1;
|
||||
subheaders[i].parent = this;
|
||||
subheaders[i].init();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace srsue
|
||||
|
||||
|
||||
#endif // MACPDU_H
|
||||
|
||||
#endif // SRSLTE_PDU_H
|
||||
|
|
|
@ -41,29 +41,35 @@ namespace srslte {
|
|||
class pdu_queue
|
||||
{
|
||||
public:
|
||||
typedef enum {
|
||||
DCH,
|
||||
BCH,
|
||||
MCH
|
||||
} channel_t;
|
||||
class process_callback
|
||||
{
|
||||
public:
|
||||
virtual void process_pdu(uint8_t *buff, uint32_t len, uint32_t tstamp) = 0;
|
||||
public:
|
||||
virtual void process_pdu(uint8_t *buff, uint32_t len, channel_t channel, uint32_t tstamp) = 0;
|
||||
};
|
||||
|
||||
pdu_queue(uint32_t pool_size = DEFAULT_POOL_SIZE) : pool(pool_size), callback(NULL), log_h(NULL) {}
|
||||
void init(process_callback *callback, log* log_h_);
|
||||
|
||||
uint8_t* request(uint32_t len);
|
||||
uint8_t* request(uint32_t len);
|
||||
void deallocate(uint8_t* pdu);
|
||||
void push(uint8_t *ptr, uint32_t len, uint32_t tstamp = 0);
|
||||
|
||||
void push(uint8_t *ptr, uint32_t len, channel_t channel = DCH, uint32_t tstamp = 0);
|
||||
|
||||
bool process_pdus();
|
||||
|
||||
|
||||
private:
|
||||
const static int DEFAULT_POOL_SIZE = 64; // Number of PDU buffers in total
|
||||
const static int MAX_PDU_LEN = 150*1024/8; // ~ 150 Mbps
|
||||
|
||||
const static int DEFAULT_POOL_SIZE = 64; // Number of PDU buffers in total
|
||||
const static int MAX_PDU_LEN = 150*1024/8; // ~ 150 Mbps
|
||||
|
||||
typedef struct {
|
||||
uint8_t ptr[MAX_PDU_LEN];
|
||||
uint32_t len;
|
||||
uint32_t tstamp;
|
||||
uint8_t ptr[MAX_PDU_LEN];
|
||||
uint32_t len;
|
||||
uint32_t tstamp;
|
||||
channel_t channel;
|
||||
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
|
||||
char debug_name[128];
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsUE library.
|
||||
*
|
||||
* srsUE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsUE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RLCPCAP_H
|
||||
#define RLCPCAP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "srslte/common/pcap.h"
|
||||
|
||||
namespace srslte {
|
||||
|
||||
class rlc_pcap
|
||||
{
|
||||
public:
|
||||
rlc_pcap() {enable_write=false; ue_id=0; pcap_file = NULL; };
|
||||
void enable(bool en);
|
||||
void open(const char *filename, uint32_t ue_id = 0);
|
||||
void close();
|
||||
|
||||
void set_ue_id(uint16_t ue_id);
|
||||
|
||||
void write_dl_am_ccch(uint8_t* pdu, uint32_t pdu_len_bytes);
|
||||
void write_ul_am_ccch(uint8_t* pdu, uint32_t pdu_len_bytes);
|
||||
|
||||
private:
|
||||
bool enable_write;
|
||||
FILE *pcap_file;
|
||||
uint32_t ue_id;
|
||||
void pack_and_write(uint8_t* pdu,
|
||||
uint32_t pdu_len_bytes,
|
||||
uint8_t mode,
|
||||
uint8_t direction,
|
||||
uint8_t priority,
|
||||
uint8_t seqnumberlength,
|
||||
uint16_t ueid,
|
||||
uint16_t channel_type,
|
||||
uint16_t channel_id);
|
||||
};
|
||||
|
||||
} // namespace srsue
|
||||
|
||||
#endif // RLCPCAP_H
|
|
@ -109,7 +109,7 @@ uint8_t security_generate_k_up( uint8_t *k_enb,
|
|||
|
||||
uint8_t security_128_eia1( uint8_t *key,
|
||||
uint32_t count,
|
||||
uint8_t bearer,
|
||||
uint32_t bearer,
|
||||
uint8_t direction,
|
||||
uint8_t *msg,
|
||||
uint32_t msg_len,
|
||||
|
@ -117,12 +117,17 @@ uint8_t security_128_eia1( uint8_t *key,
|
|||
|
||||
uint8_t security_128_eia2( uint8_t *key,
|
||||
uint32_t count,
|
||||
uint8_t bearer,
|
||||
uint32_t bearer,
|
||||
uint8_t direction,
|
||||
uint8_t *msg,
|
||||
uint32_t msg_len,
|
||||
uint8_t *mac);
|
||||
|
||||
uint8_t security_md5(const uint8_t *input,
|
||||
size_t len,
|
||||
uint8_t *output);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Encryption / Decryption
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -89,7 +89,7 @@ public:
|
|||
period_us = period_us_;
|
||||
start(priority);
|
||||
}
|
||||
void stop() {
|
||||
void stop_thread() {
|
||||
run_enable = false;
|
||||
wait_thread_finish();
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
return (counter < timeout) && running;
|
||||
}
|
||||
bool is_expired() {
|
||||
return (timeout > 0) && (counter >= timeout || !running);
|
||||
return (timeout > 0) && (counter >= timeout);
|
||||
}
|
||||
uint32_t get_timeout() {
|
||||
return timeout;
|
||||
|
@ -143,7 +143,7 @@ public:
|
|||
used_timers[i] = false;
|
||||
nof_used_timers--;
|
||||
} else {
|
||||
fprintf(stderr, "Error releasing timer: nof_used_timers=%d, nof_timers=%d\n", nof_used_timers, nof_timers);
|
||||
fprintf(stderr, "Error releasing timer id=%d: nof_used_timers=%d, nof_timers=%d\n", i, nof_used_timers, nof_timers);
|
||||
}
|
||||
}
|
||||
uint32_t get_unique_id() {
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
virtual int crc_info(uint32_t tti, uint16_t rnti, uint32_t nof_bytes, bool crc_res) = 0;
|
||||
|
||||
virtual int get_dl_sched(uint32_t tti, dl_sched_t *dl_sched_res) = 0;
|
||||
virtual int get_mch_sched(bool is_mcch, dl_sched_t *dl_sched_res) = 0;
|
||||
virtual int get_ul_sched(uint32_t tti, ul_sched_t *ul_sched_res) = 0;
|
||||
|
||||
// Radio-Link status
|
||||
|
@ -95,6 +96,20 @@ public:
|
|||
class phy_interface_rrc
|
||||
{
|
||||
public:
|
||||
|
||||
typedef struct {
|
||||
LIBLTE_RRC_MBSFN_SUBFRAME_CONFIG_STRUCT mbsfn_subfr_cnfg;
|
||||
LIBLTE_RRC_MBSFN_NOTIFICATION_CONFIG_STRUCT mbsfn_notification_cnfg;
|
||||
LIBLTE_RRC_MBSFN_AREA_INFO_STRUCT mbsfn_area_info;
|
||||
LIBLTE_RRC_MCCH_MSG_STRUCT mcch;
|
||||
} phy_cfg_mbsfn_t;
|
||||
|
||||
typedef struct {
|
||||
phy_cfg_mbsfn_t mbsfn;
|
||||
} phy_rrc_cfg_t;
|
||||
|
||||
|
||||
virtual void configure_mbsfn(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13_STRUCT *sib13, LIBLTE_RRC_MCCH_MSG_STRUCT mcch) = 0;
|
||||
virtual void set_conf_dedicated_ack(uint16_t rnti, bool rrc_completed) = 0;
|
||||
virtual void set_config_dedicated(uint16_t rnti, LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT* dedicated) = 0;
|
||||
|
||||
|
@ -116,7 +131,7 @@ public:
|
|||
virtual int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) = 0;
|
||||
virtual int set_dl_ant_info(uint16_t rnti, LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT *dl_ant_info) = 0;
|
||||
virtual void phy_config_enabled(uint16_t rnti, bool enabled) = 0;
|
||||
|
||||
virtual void write_mcch(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13_STRUCT *sib13, LIBLTE_RRC_MCCH_MSG_STRUCT *mcch) = 0;
|
||||
};
|
||||
|
||||
class mac_interface_rlc
|
||||
|
@ -164,6 +179,7 @@ public:
|
|||
virtual void rem_user(uint16_t rnti) = 0;
|
||||
virtual void add_bearer(uint16_t rnti, uint32_t lcid) = 0;
|
||||
virtual void add_bearer(uint16_t rnti, uint32_t lcid, srslte::srslte_rlc_config_t cnfg) = 0;
|
||||
virtual void add_bearer_mrb(uint16_t rnti, uint32_t lcid) = 0;
|
||||
};
|
||||
|
||||
// PDCP interface for GTPU
|
||||
|
@ -262,9 +278,7 @@ public:
|
|||
virtual void initial_ue(uint16_t rnti, srslte::byte_buffer_t *pdu, uint32_t m_tmsi, uint8_t mmec) = 0;
|
||||
virtual void write_pdu(uint16_t rnti, srslte::byte_buffer_t *pdu) = 0;
|
||||
virtual bool user_exists(uint16_t rnti) = 0;
|
||||
virtual void user_inactivity(uint16_t rnti) = 0;
|
||||
virtual void release_eutran(uint16_t rnti) = 0;
|
||||
virtual bool user_link_lost(uint16_t rnti) = 0;
|
||||
virtual bool user_release(uint16_t rnti, LIBLTE_S1AP_CAUSERADIONETWORK_ENUM cause_radio) = 0;
|
||||
virtual void ue_ctxt_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *res) = 0;
|
||||
virtual void ue_erab_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT *res) = 0;
|
||||
// virtual void ue_capabilities(uint16_t rnti, LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *caps) = 0;
|
||||
|
|
|
@ -129,6 +129,22 @@ public:
|
|||
uint32_t nbytes;
|
||||
} dl_sched_pdu_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t lcid;
|
||||
uint32_t lcid_buffer_size;
|
||||
uint32_t stop;
|
||||
uint8_t *mtch_payload;
|
||||
} dl_mtch_sched_t;
|
||||
|
||||
typedef struct {
|
||||
dl_sched_pdu_t pdu[20];
|
||||
dl_mtch_sched_t mtch_sched[8];
|
||||
uint32_t num_mtch_sched;
|
||||
uint8_t *mcch_payload;
|
||||
uint32_t current_sf_allocation_num;
|
||||
} dl_pdu_mch_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t rnti;
|
||||
srslte_dci_format_t dci_format;
|
||||
|
|
|
@ -43,6 +43,12 @@
|
|||
|
||||
namespace srsue {
|
||||
|
||||
typedef enum {
|
||||
AUTH_OK,
|
||||
AUTH_FAILED,
|
||||
AUTH_SYNCH_FAILURE
|
||||
} auth_result_t;
|
||||
|
||||
// UE interface
|
||||
class ue_interface
|
||||
{
|
||||
|
@ -57,12 +63,12 @@ public:
|
|||
virtual bool get_imsi_vec(uint8_t* imsi_, uint32_t n) = 0;
|
||||
virtual bool get_imei_vec(uint8_t* imei_, uint32_t n) = 0;
|
||||
virtual bool get_home_plmn_id(LIBLTE_RRC_PLMN_IDENTITY_STRUCT *home_plmn_id) = 0;
|
||||
virtual void generate_authentication_response(uint8_t *rand,
|
||||
virtual auth_result_t generate_authentication_response(uint8_t *rand,
|
||||
uint8_t *autn_enb,
|
||||
uint16_t mcc,
|
||||
uint16_t mnc,
|
||||
bool *net_valid,
|
||||
uint8_t *res,
|
||||
int *res_len,
|
||||
uint8_t *k_asme) = 0;
|
||||
virtual void generate_nas_keys(uint8_t *k_asme,
|
||||
uint8_t *k_nas_enc,
|
||||
|
@ -101,41 +107,53 @@ public:
|
|||
virtual srslte::error_t setup_if_addr(uint32_t ip_addr, char *err_str) = 0;
|
||||
};
|
||||
|
||||
// GW interface for RRC
|
||||
class gw_interface_rrc
|
||||
{
|
||||
public:
|
||||
virtual void add_mch_port(uint32_t lcid, uint32_t port) = 0;
|
||||
};
|
||||
|
||||
// GW interface for PDCP
|
||||
class gw_interface_pdcp
|
||||
{
|
||||
public:
|
||||
virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0;
|
||||
virtual void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0;
|
||||
};
|
||||
|
||||
// NAS interface for RRC
|
||||
class nas_interface_rrc
|
||||
{
|
||||
public:
|
||||
typedef enum {
|
||||
BARRING_NONE = 0,
|
||||
BARRING_MO_DATA,
|
||||
BARRING_MO_SIGNALLING,
|
||||
BARRING_MT,
|
||||
BARRING_ALL
|
||||
} barring_t;
|
||||
virtual void set_barring(barring_t barring) = 0;
|
||||
virtual void paging(LIBLTE_RRC_S_TMSI_STRUCT *ue_identiy) = 0;
|
||||
virtual bool is_attached() = 0;
|
||||
virtual bool is_attaching() = 0;
|
||||
virtual void notify_connection_setup() = 0;
|
||||
virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0;
|
||||
virtual uint32_t get_ul_count() = 0;
|
||||
virtual bool get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi) = 0;
|
||||
virtual bool get_k_asme(uint8_t *k_asme_, uint32_t n) = 0;
|
||||
virtual bool plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) = 0;
|
||||
virtual void plmn_search_end() = 0;
|
||||
};
|
||||
|
||||
// NAS interface for UE
|
||||
class nas_interface_ue
|
||||
{
|
||||
public:
|
||||
virtual void attach_request() = 0;
|
||||
virtual void deattach_request() = 0;
|
||||
virtual bool attach_request() = 0;
|
||||
virtual bool deattach_request() = 0;
|
||||
};
|
||||
|
||||
// NAS interface for UE
|
||||
class nas_interface_gw
|
||||
{
|
||||
public:
|
||||
virtual void attach_request() = 0;
|
||||
virtual bool attach_request() = 0;
|
||||
};
|
||||
|
||||
// RRC interface for MAC
|
||||
|
@ -159,8 +177,6 @@ class rrc_interface_phy
|
|||
public:
|
||||
virtual void in_sync() = 0;
|
||||
virtual void out_of_sync() = 0;
|
||||
virtual void earfcn_end() = 0;
|
||||
virtual void cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp = NAN) = 0;
|
||||
virtual void new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn = -1, int pci = -1) = 0;
|
||||
};
|
||||
|
||||
|
@ -168,12 +184,23 @@ public:
|
|||
class rrc_interface_nas
|
||||
{
|
||||
public:
|
||||
typedef struct {
|
||||
LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id;
|
||||
uint16_t tac;
|
||||
} found_plmn_t;
|
||||
|
||||
const static int MAX_FOUND_PLMNS = 16;
|
||||
|
||||
virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
|
||||
virtual uint16_t get_mcc() = 0;
|
||||
virtual uint16_t get_mnc() = 0;
|
||||
virtual void enable_capabilities() = 0;
|
||||
virtual void plmn_search() = 0;
|
||||
virtual void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, bool connect_request = false) = 0;
|
||||
virtual int plmn_search(found_plmn_t found_plmns[MAX_FOUND_PLMNS]) = 0;
|
||||
virtual void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) = 0;
|
||||
virtual bool connection_request(LIBLTE_RRC_CON_REQ_EST_CAUSE_ENUM cause,
|
||||
srslte::byte_buffer_t *dedicatedInfoNAS) = 0;
|
||||
virtual void set_ue_idenity(LIBLTE_RRC_S_TMSI_STRUCT s_tmsi) = 0;
|
||||
virtual bool is_connected() = 0;
|
||||
virtual std::string get_rb_name(uint32_t lcid) = 0;
|
||||
};
|
||||
|
||||
|
@ -185,6 +212,7 @@ public:
|
|||
virtual void write_pdu_bcch_bch(srslte::byte_buffer_t *pdu) = 0;
|
||||
virtual void write_pdu_bcch_dlsch(srslte::byte_buffer_t *pdu) = 0;
|
||||
virtual void write_pdu_pcch(srslte::byte_buffer_t *pdu) = 0;
|
||||
virtual void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0;
|
||||
virtual std::string get_rb_name(uint32_t lcid) = 0;
|
||||
};
|
||||
|
||||
|
@ -234,6 +262,7 @@ public:
|
|||
virtual void write_pdu_bcch_bch(srslte::byte_buffer_t *sdu) = 0;
|
||||
virtual void write_pdu_bcch_dlsch(srslte::byte_buffer_t *sdu) = 0;
|
||||
virtual void write_pdu_pcch(srslte::byte_buffer_t *sdu) = 0;
|
||||
virtual void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
|
||||
};
|
||||
|
||||
// RLC interface for RRC
|
||||
|
@ -244,6 +273,7 @@ public:
|
|||
virtual void reestablish() = 0;
|
||||
virtual void add_bearer(uint32_t lcid) = 0;
|
||||
virtual void add_bearer(uint32_t lcid, srslte::srslte_rlc_config_t cnfg) = 0;
|
||||
virtual void add_bearer_mrb(uint32_t lcid) = 0;
|
||||
};
|
||||
|
||||
// RLC interface for PDCP
|
||||
|
@ -278,6 +308,7 @@ public:
|
|||
virtual void write_pdu_bcch_bch(uint8_t *payload, uint32_t nof_bytes) = 0;
|
||||
virtual void write_pdu_bcch_dlsch(uint8_t *payload, uint32_t nof_bytes) = 0;
|
||||
virtual void write_pdu_pcch(uint8_t *payload, uint32_t nof_bytes) = 0;
|
||||
virtual void write_pdu_mch(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -314,6 +345,11 @@ public:
|
|||
class mac_interface_phy
|
||||
{
|
||||
public:
|
||||
typedef struct {
|
||||
uint32_t nof_mbsfn_services;
|
||||
} mac_phy_cfg_mbsfn_t;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t pid;
|
||||
|
@ -366,26 +402,35 @@ public:
|
|||
/* Indicate reception of UL grant + HARQ information throught PHICH in the same TTI. */
|
||||
virtual void new_grant_ul_ack(mac_grant_t grant, bool ack, tb_action_ul_t *action) = 0;
|
||||
|
||||
/* Obtain action for a new MCH subframe. */
|
||||
virtual void new_mch_dl(srslte_ra_dl_grant_t phy_grant, tb_action_dl_t *action) = 0;
|
||||
|
||||
/* Indicate reception of HARQ information only through PHICH. */
|
||||
virtual void harq_recv(uint32_t tti, bool ack, tb_action_ul_t *action) = 0;
|
||||
|
||||
/* Indicate reception of DL grant. */
|
||||
virtual void new_grant_dl(mac_grant_t grant, tb_action_dl_t *action) = 0;
|
||||
|
||||
/* Indicate successfull decoding of PDSCH TB. */
|
||||
/* Indicate successful decoding of PDSCH TB. */
|
||||
virtual void tb_decoded(bool ack, uint32_t tb_idx, srslte_rnti_type_t rnti_type, uint32_t harq_pid) = 0;
|
||||
|
||||
/* Indicate successfull decoding of BCH TB through PBCH */
|
||||
/* Indicate successful decoding of BCH TB through PBCH */
|
||||
virtual void bch_decoded_ok(uint8_t *payload, uint32_t len) = 0;
|
||||
|
||||
/* Indicate successfull decoding of PCH TB through PDSCH */
|
||||
/* Indicate successful decoding of PCH TB through PDSCH */
|
||||
virtual void pch_decoded_ok(uint32_t len) = 0;
|
||||
|
||||
/* Indicate successful decoding of MCH TB through PMCH */
|
||||
virtual void mch_decoded_ok(uint32_t len) = 0;
|
||||
|
||||
/* Communicate the number of mbsfn services available */
|
||||
virtual void set_mbsfn_config(uint32_t nof_mbsfn_services) = 0;
|
||||
|
||||
/* Function called every start of a subframe (TTI). Warning, this function is called
|
||||
* from a high priority thread and should terminate asap
|
||||
*/
|
||||
virtual void tti_clock(uint32_t tti) = 0;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
/* Interface RRC -> MAC shared between different RATs */
|
||||
|
@ -420,18 +465,20 @@ public:
|
|||
uint32_t prach_config_index;
|
||||
} mac_cfg_t;
|
||||
|
||||
virtual void clear_rntis() = 0;
|
||||
|
||||
/* Instructs the MAC to start receiving BCCH */
|
||||
virtual void bcch_start_rx() = 0;
|
||||
virtual void bcch_stop_rx() = 0;
|
||||
virtual void bcch_start_rx(int si_window_start, int si_window_length) = 0;
|
||||
|
||||
/* Instructs the MAC to start receiving PCCH */
|
||||
virtual void pcch_start_rx() = 0;
|
||||
virtual void pcch_stop_rx() = 0;
|
||||
|
||||
|
||||
/* RRC configures a logical channel */
|
||||
virtual void setup_lcid(uint32_t lcid, uint32_t lcg, uint32_t priority, int PBR_x_tti, uint32_t BSD) = 0;
|
||||
|
||||
/* Instructs the MAC to start receiving an MCH */
|
||||
virtual void mch_start_rx(uint32_t lcid) = 0;
|
||||
|
||||
virtual uint32_t get_current_tti() = 0;
|
||||
|
||||
virtual void set_config(mac_cfg_t *mac_cfg) = 0;
|
||||
|
@ -453,8 +500,6 @@ public:
|
|||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/** PHY interface
|
||||
*
|
||||
*/
|
||||
|
@ -484,12 +529,15 @@ typedef struct {
|
|||
float cfo_loop_bw_ref;
|
||||
float cfo_loop_ref_min;
|
||||
float cfo_loop_pss_tol;
|
||||
float sfo_ema;
|
||||
uint32_t sfo_correct_period;
|
||||
uint32_t cfo_loop_pss_conv;
|
||||
uint32_t cfo_ref_mask;
|
||||
bool average_subframe_enabled;
|
||||
int time_correct_period;
|
||||
bool estimator_fil_auto;
|
||||
float estimator_fil_stddev;
|
||||
uint32_t estimator_fil_order;
|
||||
std::string sss_algorithm;
|
||||
float estimator_fil_w;
|
||||
bool rssi_sensor_enabled;
|
||||
bool sic_pss_enabled;
|
||||
float rx_gain_offset;
|
||||
|
@ -503,9 +551,7 @@ typedef struct {
|
|||
class phy_interface_mac_common
|
||||
{
|
||||
public:
|
||||
/* Start synchronization with strongest cell in the current carrier frequency */
|
||||
virtual bool sync_status() = 0;
|
||||
|
||||
|
||||
/* Sets a C-RNTI allowing the PHY to pregenerate signals if necessary */
|
||||
virtual void set_crnti(uint16_t rnti) = 0;
|
||||
|
||||
|
@ -526,12 +572,12 @@ public:
|
|||
class phy_interface_mac : public phy_interface_mac_common
|
||||
{
|
||||
public:
|
||||
|
||||
/* Configure PRACH using parameters written by RRC */
|
||||
virtual void configure_prach_params() = 0;
|
||||
|
||||
virtual void prach_send(uint32_t preamble_idx, int allowed_subframe, float target_power_dbm) = 0;
|
||||
virtual int prach_tx_tti() = 0;
|
||||
|
||||
virtual int prach_tx_tti() = 0;
|
||||
/* Indicates the transmission of a SR signal in the next opportunity */
|
||||
virtual void sr_send() = 0;
|
||||
virtual int sr_last_tx_tti() = 0;
|
||||
|
@ -541,6 +587,9 @@ public:
|
|||
virtual void pdcch_dl_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1) = 0;
|
||||
virtual void pdcch_ul_search_reset() = 0;
|
||||
virtual void pdcch_dl_search_reset() = 0;
|
||||
|
||||
virtual void set_mch_period_stop(uint32_t stop) = 0;
|
||||
|
||||
};
|
||||
|
||||
class phy_interface_rrc
|
||||
|
@ -558,10 +607,19 @@ public:
|
|||
LIBLTE_RRC_TDD_CONFIG_STRUCT tdd_cnfg;
|
||||
LIBLTE_RRC_ANTENNA_PORTS_COUNT_ENUM ant_info;
|
||||
} phy_cfg_common_t;
|
||||
|
||||
typedef struct {
|
||||
LIBLTE_RRC_MBSFN_SUBFRAME_CONFIG_STRUCT mbsfn_subfr_cnfg;
|
||||
LIBLTE_RRC_MBSFN_NOTIFICATION_CONFIG_STRUCT mbsfn_notification_cnfg;
|
||||
LIBLTE_RRC_MBSFN_AREA_INFO_STRUCT mbsfn_area_info;
|
||||
LIBLTE_RRC_MCCH_MSG_STRUCT mcch;
|
||||
} phy_cfg_mbsfn_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT dedicated;
|
||||
phy_cfg_common_t common;
|
||||
phy_cfg_mbsfn_t mbsfn;
|
||||
bool enable_64qam;
|
||||
} phy_cfg_t;
|
||||
|
||||
|
@ -575,21 +633,29 @@ public:
|
|||
virtual void set_config_common(phy_cfg_common_t *common) = 0;
|
||||
virtual void set_config_tdd(LIBLTE_RRC_TDD_CONFIG_STRUCT *tdd) = 0;
|
||||
virtual void set_config_64qam_en(bool enable) = 0;
|
||||
virtual void set_config_mbsfn_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2) = 0;
|
||||
virtual void set_config_mbsfn_sib13(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13_STRUCT *sib13) = 0;
|
||||
virtual void set_config_mbsfn_mcch(LIBLTE_RRC_MCCH_MSG_STRUCT *mcch) = 0;
|
||||
|
||||
/* Measurements interface */
|
||||
virtual void meas_reset() = 0;
|
||||
virtual int meas_start(uint32_t earfcn, int pci = -1) = 0;
|
||||
virtual int meas_stop(uint32_t earfcn, int pci = -1) = 0;
|
||||
|
||||
/* Cell search and selection procedures */
|
||||
virtual void cell_search_start() = 0;
|
||||
virtual void cell_search_next() = 0;
|
||||
virtual void cell_select(uint32_t earfcn, srslte_cell_t cell) = 0;
|
||||
virtual bool cell_handover(srslte_cell_t cell) = 0;
|
||||
typedef struct {
|
||||
enum {CELL_FOUND = 0, CELL_NOT_FOUND, ERROR} found;
|
||||
enum {MORE_FREQS = 0, NO_MORE_FREQS} last_freq;
|
||||
} cell_search_ret_t;
|
||||
|
||||
/* Is the PHY downlink synchronized? */
|
||||
virtual bool sync_status() = 0;
|
||||
virtual void sync_reset() = 0;
|
||||
typedef struct {
|
||||
srslte_cell_t cell;
|
||||
uint32_t earfcn;
|
||||
} phy_cell_t;
|
||||
|
||||
/* Cell search and selection procedures */
|
||||
virtual cell_search_ret_t cell_search(phy_cell_t *cell) = 0;
|
||||
virtual bool cell_select(phy_cell_t *cell = NULL) = 0;
|
||||
virtual bool cell_is_camping() = 0;
|
||||
|
||||
/* Configure UL using parameters written with set_param() */
|
||||
virtual void configure_ul_params(bool pregen_disabled = false) = 0;
|
||||
|
|
|
@ -53,6 +53,8 @@ typedef enum SRSLTE_API {
|
|||
typedef struct SRSLTE_API{
|
||||
float bandwidth;
|
||||
double gain;
|
||||
double min_gain;
|
||||
double max_gain;
|
||||
float y_out;
|
||||
bool lock;
|
||||
bool isfirst;
|
||||
|
@ -79,6 +81,8 @@ SRSLTE_API void srslte_agc_free(srslte_agc_t *q);
|
|||
|
||||
SRSLTE_API void srslte_agc_reset(srslte_agc_t *q);
|
||||
|
||||
SRSLTE_API void srslte_agc_set_gain_range(srslte_agc_t *q, double min_gain, double max_gain);
|
||||
|
||||
SRSLTE_API void srslte_agc_set_bandwidth(srslte_agc_t *q,
|
||||
float bandwidth);
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ typedef struct {
|
|||
float snr_vector[12000];
|
||||
float pilot_power[12000];
|
||||
#endif
|
||||
bool smooth_filter_auto;
|
||||
uint32_t smooth_filter_len;
|
||||
float smooth_filter[SRSLTE_CHEST_MAX_SMOOTH_FIL_LEN];
|
||||
|
||||
|
@ -112,10 +113,10 @@ SRSLTE_API void srslte_chest_dl_free(srslte_chest_dl_t *q);
|
|||
|
||||
SRSLTE_API int srslte_chest_dl_set_mbsfn_area_id(srslte_chest_dl_t *q,
|
||||
uint16_t mbsfn_area_id);
|
||||
|
||||
SRSLTE_API int srslte_chest_dl_set_cell(srslte_chest_dl_t *q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
|
||||
SRSLTE_API void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q,
|
||||
float *filter,
|
||||
uint32_t filter_len);
|
||||
|
@ -123,6 +124,13 @@ SRSLTE_API void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q,
|
|||
SRSLTE_API void srslte_chest_dl_set_smooth_filter3_coeff(srslte_chest_dl_t* q,
|
||||
float w);
|
||||
|
||||
SRSLTE_API void srslte_chest_dl_set_smooth_filter_gauss(srslte_chest_dl_t* q,
|
||||
uint32_t order,
|
||||
float std_dev);
|
||||
|
||||
SRSLTE_API void srslte_chest_dl_set_smooth_filter_auto(srslte_chest_dl_t* q,
|
||||
bool enable);
|
||||
|
||||
SRSLTE_API void srslte_chest_dl_set_noise_alg(srslte_chest_dl_t *q,
|
||||
srslte_chest_dl_noise_alg_t noise_estimation_alg);
|
||||
|
||||
|
|
|
@ -93,8 +93,10 @@ SRSLTE_API uint32_t srslte_refsignal_cs_v(uint32_t port_id,
|
|||
|
||||
SRSLTE_API uint32_t srslte_refsignal_cs_nof_symbols(uint32_t port_id);
|
||||
|
||||
SRSLTE_API int srslte_refsignal_mbsfn_init(srslte_refsignal_t *q, srslte_cell_t cell,
|
||||
uint16_t mbsfn_area_id);
|
||||
SRSLTE_API int srslte_refsignal_mbsfn_init(srslte_refsignal_t *q, uint32_t max_prb);
|
||||
|
||||
SRSLTE_API int srslte_refsignal_mbsfn_set_cell(srslte_refsignal_t * q,
|
||||
srslte_cell_t cell, uint16_t mbsfn_area_id);
|
||||
|
||||
SRSLTE_API int srslte_refsignal_mbsfn_get_sf(srslte_cell_t cell,
|
||||
uint32_t port_id,
|
||||
|
|
|
@ -92,7 +92,7 @@ SRSLTE_API int srslte_ofdm_rx_init_mbsfn(srslte_ofdm_t *q,
|
|||
srslte_cp_t cp_type,
|
||||
cf_t *in_buffer,
|
||||
cf_t *out_buffer,
|
||||
uint32_t nof_prb);
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API int srslte_ofdm_rx_init(srslte_ofdm_t *q,
|
||||
srslte_cp_t cp_type,
|
||||
|
|
|
@ -69,15 +69,20 @@ typedef struct SRSLTE_API {
|
|||
cf_t *slot1_symbols[SRSLTE_MAX_PORTS];
|
||||
|
||||
srslte_ofdm_t ifft[SRSLTE_MAX_PORTS];
|
||||
|
||||
srslte_ofdm_t ifft_mbsfn;
|
||||
srslte_pbch_t pbch;
|
||||
srslte_pcfich_t pcfich;
|
||||
srslte_regs_t regs;
|
||||
srslte_pdcch_t pdcch;
|
||||
srslte_pdsch_t pdsch;
|
||||
srslte_pmch_t pmch;
|
||||
srslte_phich_t phich;
|
||||
|
||||
srslte_refsignal_t csr_signal;
|
||||
srslte_pdsch_cfg_t pdsch_cfg;
|
||||
srslte_refsignal_t mbsfnr_signal;
|
||||
srslte_pdsch_cfg_t pdsch_cfg;
|
||||
srslte_pdsch_cfg_t pmch_cfg;
|
||||
srslte_ra_dl_dci_t dl_dci;
|
||||
|
||||
srslte_dci_format_t dci_format;
|
||||
|
@ -134,6 +139,8 @@ SRSLTE_API void srslte_enb_dl_prepare_power_allocation(srslte_enb_dl_t *q);
|
|||
SRSLTE_API void srslte_enb_dl_set_amp(srslte_enb_dl_t *q,
|
||||
float amp);
|
||||
|
||||
SRSLTE_API void srslte_enb_dl_set_non_mbsfn_region(srslte_enb_dl_t *q, uint8_t non_mbsfn_region);
|
||||
|
||||
SRSLTE_API void srslte_enb_dl_clear_sf(srslte_enb_dl_t *q);
|
||||
|
||||
SRSLTE_API void srslte_enb_dl_put_sync(srslte_enb_dl_t *q,
|
||||
|
@ -157,8 +164,13 @@ SRSLTE_API void srslte_enb_dl_put_phich(srslte_enb_dl_t *q,
|
|||
SRSLTE_API void srslte_enb_dl_put_base(srslte_enb_dl_t *q,
|
||||
uint32_t tti);
|
||||
|
||||
SRSLTE_API void srslte_enb_dl_put_mbsfn_base(srslte_enb_dl_t *q,
|
||||
uint32_t tti);
|
||||
|
||||
SRSLTE_API void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q);
|
||||
|
||||
SRSLTE_API void srslte_enb_dl_gen_signal_mbsfn(srslte_enb_dl_t *q);
|
||||
|
||||
SRSLTE_API int srslte_enb_dl_add_rnti(srslte_enb_dl_t *q,
|
||||
uint16_t rnti);
|
||||
|
||||
|
@ -174,6 +186,12 @@ SRSLTE_API int srslte_enb_dl_put_pdsch(srslte_enb_dl_t *q,
|
|||
uint8_t *data[SRSLTE_MAX_CODEWORDS],
|
||||
srslte_mimo_type_t mimo_type);
|
||||
|
||||
SRSLTE_API int srslte_enb_dl_put_pmch(srslte_enb_dl_t *q,
|
||||
srslte_ra_dl_grant_t *grant,
|
||||
srslte_softbuffer_tx_t *softbuffer,
|
||||
uint32_t sf_idx,
|
||||
uint8_t *data_mbms);
|
||||
|
||||
SRSLTE_API int srslte_enb_dl_put_pdcch_dl(srslte_enb_dl_t *q,
|
||||
srslte_ra_dl_dci_t *grant,
|
||||
srslte_dci_format_t format,
|
||||
|
|
|
@ -87,7 +87,7 @@ SRSLTE_API int srslte_predecoding_single(cf_t *y,
|
|||
SRSLTE_API int srslte_predecoding_single_multi(cf_t *y[SRSLTE_MAX_PORTS],
|
||||
cf_t *h[SRSLTE_MAX_PORTS],
|
||||
cf_t *x,
|
||||
float *csi,
|
||||
float *csi[SRSLTE_MAX_CODEWORDS],
|
||||
int nof_rxant,
|
||||
int nof_symbols,
|
||||
float scaling,
|
||||
|
@ -102,7 +102,8 @@ SRSLTE_API int srslte_predecoding_diversity(cf_t *y,
|
|||
|
||||
SRSLTE_API int srslte_predecoding_diversity_multi(cf_t *y[SRSLTE_MAX_PORTS],
|
||||
cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
|
||||
cf_t *x[SRSLTE_MAX_LAYERS],
|
||||
cf_t *x[SRSLTE_MAX_LAYERS],
|
||||
float *csi[SRSLTE_MAX_LAYERS],
|
||||
int nof_rxant,
|
||||
int nof_ports,
|
||||
int nof_symbols,
|
||||
|
@ -113,7 +114,7 @@ SRSLTE_API void srslte_predecoding_set_mimo_decoder (srslte_mimo_decoder_t _mimo
|
|||
SRSLTE_API int srslte_predecoding_type(cf_t *y[SRSLTE_MAX_PORTS],
|
||||
cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
|
||||
cf_t *x[SRSLTE_MAX_LAYERS],
|
||||
float *csi,
|
||||
float *csi[SRSLTE_MAX_CODEWORDS],
|
||||
int nof_rxant,
|
||||
int nof_ports,
|
||||
int nof_layers,
|
||||
|
|
|
@ -89,6 +89,8 @@ typedef struct SRSLTE_API {
|
|||
|
||||
srslte_sch_t dl_sch;
|
||||
|
||||
void *coworker_ptr;
|
||||
|
||||
} srslte_pdsch_t;
|
||||
|
||||
|
||||
|
@ -167,6 +169,8 @@ SRSLTE_API void srslte_pdsch_set_max_noi(srslte_pdsch_t *q,
|
|||
|
||||
SRSLTE_API float srslte_pdsch_last_noi(srslte_pdsch_t *q);
|
||||
|
||||
SRSLTE_API int srslte_pdsch_enable_coworker(srslte_pdsch_t *q);
|
||||
|
||||
SRSLTE_API uint32_t srslte_pdsch_last_noi_cw(srslte_pdsch_t *q,
|
||||
uint32_t cw_idx);
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ SRSLTE_API int srslte_pmch_init_multi(srslte_pmch_t *q,
|
|||
|
||||
SRSLTE_API void srslte_pmch_free(srslte_pmch_t *q);
|
||||
|
||||
|
||||
SRSLTE_API int srslte_pmch_set_cell(srslte_pmch_t *q, srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API int srslte_pmch_set_area_id(srslte_pmch_t *q, uint16_t area_id);
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ typedef struct SRSLTE_API {
|
|||
uint8_t *parity_bits;
|
||||
void *e;
|
||||
uint8_t *temp_g_bits;
|
||||
uint16_t *ul_interleaver;
|
||||
uint32_t *ul_interleaver;
|
||||
srslte_uci_bit_t ack_ri_bits[12*288];
|
||||
uint32_t nof_ri_ack_bits;
|
||||
|
||||
|
|
|
@ -55,6 +55,14 @@ typedef struct {
|
|||
float iq_q;
|
||||
} srslte_rf_cal_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
double min_tx_gain;
|
||||
double max_tx_gain;
|
||||
double min_rx_gain;
|
||||
double max_rx_gain;
|
||||
} srslte_rf_info_t;
|
||||
|
||||
typedef struct {
|
||||
enum {
|
||||
SRSLTE_RF_ERROR_LATE,
|
||||
|
@ -125,6 +133,8 @@ SRSLTE_API double srslte_rf_get_rx_gain(srslte_rf_t *h);
|
|||
|
||||
SRSLTE_API double srslte_rf_get_tx_gain(srslte_rf_t *h);
|
||||
|
||||
SRSLTE_API srslte_rf_info_t *srslte_rf_get_info(srslte_rf_t *h);
|
||||
|
||||
SRSLTE_API void srslte_rf_suppress_stdout(srslte_rf_t *h);
|
||||
|
||||
SRSLTE_API void srslte_rf_register_error_handler(srslte_rf_t *h,
|
||||
|
|
|
@ -61,6 +61,8 @@
|
|||
#include "srslte/phy/common/timestamp.h"
|
||||
#include "srslte/phy/io/filesource.h"
|
||||
|
||||
#define DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD 10
|
||||
#define DEFAULT_SFO_EMA_COEFF 0.1
|
||||
|
||||
#define DEFAULT_CFO_BW_PSS 0.05
|
||||
#define DEFAULT_CFO_PSS_MIN 400 // typical bias of PSS estimation.
|
||||
|
@ -140,8 +142,7 @@ typedef struct SRSLTE_API {
|
|||
int next_rf_sample_offset;
|
||||
int last_sample_offset;
|
||||
float mean_sample_offset;
|
||||
float mean_sfo;
|
||||
uint32_t sample_offset_correct_period;
|
||||
uint32_t sample_offset_correct_period;
|
||||
float sfo_ema;
|
||||
|
||||
|
||||
|
@ -198,7 +199,9 @@ SRSLTE_API void srslte_ue_sync_reset(srslte_ue_sync_t *q);
|
|||
|
||||
SRSLTE_API int srslte_ue_sync_start_agc(srslte_ue_sync_t *q,
|
||||
double (set_gain_callback)(void*, double),
|
||||
float init_gain_value);
|
||||
double min_gain,
|
||||
double max_gain,
|
||||
double init_gain_value);
|
||||
|
||||
SRSLTE_API uint32_t srslte_ue_sync_sf_len(srslte_ue_sync_t *q);
|
||||
|
||||
|
@ -248,8 +251,11 @@ SRSLTE_API float srslte_ue_sync_get_sfo(srslte_ue_sync_t *q);
|
|||
|
||||
SRSLTE_API int srslte_ue_sync_get_last_sample_offset(srslte_ue_sync_t *q);
|
||||
|
||||
SRSLTE_API void srslte_ue_sync_set_sample_offset_correct_period(srslte_ue_sync_t *q,
|
||||
uint32_t nof_subframes);
|
||||
SRSLTE_API void srslte_ue_sync_set_sfo_correct_period(srslte_ue_sync_t *q,
|
||||
uint32_t nof_subframes);
|
||||
|
||||
SRSLTE_API void srslte_ue_sync_set_sfo_ema(srslte_ue_sync_t *q,
|
||||
float ema_coefficient);
|
||||
|
||||
SRSLTE_API void srslte_ue_sync_get_last_timestamp(srslte_ue_sync_t *q,
|
||||
srslte_timestamp_t *timestamp);
|
||||
|
|
|
@ -70,6 +70,17 @@ SRSLTE_API void srslte_bit_copy(uint8_t *dst,
|
|||
uint32_t src_offset,
|
||||
uint32_t nof_bits);
|
||||
|
||||
SRSLTE_API void srslte_bit_interleave_i(uint8_t *input,
|
||||
uint8_t *output,
|
||||
uint32_t *interleaver,
|
||||
uint32_t nof_bits);
|
||||
|
||||
SRSLTE_API void srslte_bit_interleave_i_w_offset(uint8_t *input,
|
||||
uint8_t *output,
|
||||
uint32_t *interleaver,
|
||||
uint32_t nof_bits,
|
||||
uint32_t w_offset);
|
||||
|
||||
SRSLTE_API void srslte_bit_interleave_w_offset(uint8_t *input,
|
||||
uint8_t *output,
|
||||
uint16_t *interleaver,
|
||||
|
|
|
@ -53,12 +53,17 @@ SRSLTE_API void srslte_mat_2x2_mmse_gen(cf_t y0, cf_t y1,
|
|||
float noise_estimate,
|
||||
float norm);
|
||||
|
||||
SRSLTE_API void srslte_mat_2x2_mmse_csi_gen(cf_t y0, cf_t y1,
|
||||
cf_t h00, cf_t h01, cf_t h10, cf_t h11,
|
||||
cf_t *x0, cf_t *x1, float *csi0, float *csi1,
|
||||
float noise_estimate,
|
||||
float norm);
|
||||
|
||||
SRSLTE_API float srslte_mat_2x2_cn(cf_t h00,
|
||||
cf_t h01,
|
||||
cf_t h10,
|
||||
cf_t h11);
|
||||
|
||||
|
||||
#ifdef LV_HAVE_SSE
|
||||
|
||||
/* SSE implementation for complex reciprocal */
|
||||
|
@ -103,4 +108,114 @@ SRSLTE_API void srslte_mat_2x2_mmse_avx(__m256 y0, __m256 y1,
|
|||
|
||||
#endif /* LV_HAVE_AVX */
|
||||
|
||||
#endif // SRSLTE_MAT_H
|
||||
#if SRSLTE_SIMD_CF_SIZE != 0
|
||||
|
||||
/* Generic SIMD implementation for 2x2 determinant */
|
||||
static inline simd_cf_t srslte_mat_2x2_det_simd(simd_cf_t a00, simd_cf_t a01, simd_cf_t a10, simd_cf_t a11) {
|
||||
return srslte_simd_cf_sub(srslte_simd_cf_prod(a00, a11), srslte_simd_cf_prod(a01, a10));
|
||||
}
|
||||
|
||||
/* Generic SIMD implementation for Zero Forcing (ZF) solver */
|
||||
static inline void srslte_mat_2x2_zf_csi_simd(simd_cf_t y0,
|
||||
simd_cf_t y1,
|
||||
simd_cf_t h00,
|
||||
simd_cf_t h01,
|
||||
simd_cf_t h10,
|
||||
simd_cf_t h11,
|
||||
simd_cf_t *x0,
|
||||
simd_cf_t *x1,
|
||||
simd_f_t *csi0,
|
||||
simd_f_t *csi1,
|
||||
float norm) {
|
||||
simd_cf_t det = srslte_mat_2x2_det_simd(h00, h01, h10, h11);
|
||||
simd_cf_t detrec = srslte_simd_cf_mul(srslte_simd_cf_rcp(det), srslte_simd_f_set1(norm));
|
||||
|
||||
*x0 = srslte_simd_cf_prod(srslte_simd_cf_sub(srslte_simd_cf_prod(h11, y0), srslte_simd_cf_prod(h01, y1)), detrec);
|
||||
*x1 = srslte_simd_cf_prod(srslte_simd_cf_sub(srslte_simd_cf_prod(h00, y1), srslte_simd_cf_prod(h10, y0)), detrec);
|
||||
|
||||
*csi0 = srslte_simd_f_set1(1.0f);
|
||||
*csi1 = srslte_simd_f_set1(1.0f);
|
||||
}
|
||||
|
||||
static inline void srslte_mat_2x2_zf_simd(simd_cf_t y0,
|
||||
simd_cf_t y1,
|
||||
simd_cf_t h00,
|
||||
simd_cf_t h01,
|
||||
simd_cf_t h10,
|
||||
simd_cf_t h11,
|
||||
simd_cf_t *x0,
|
||||
simd_cf_t *x1,
|
||||
float norm) {
|
||||
simd_f_t csi1, csi2;
|
||||
srslte_mat_2x2_zf_csi_simd(y0, y1, h00, h01, h10, h11, x0, x1, &csi1, &csi2, norm);
|
||||
}
|
||||
|
||||
/* Generic SIMD implementation for Minimum Mean Squared Error (MMSE) solver */
|
||||
static inline void srslte_mat_2x2_mmse_csi_simd(simd_cf_t y0,
|
||||
simd_cf_t y1,
|
||||
simd_cf_t h00,
|
||||
simd_cf_t h01,
|
||||
simd_cf_t h10,
|
||||
simd_cf_t h11,
|
||||
simd_cf_t *x0,
|
||||
simd_cf_t *x1,
|
||||
simd_f_t *csi0,
|
||||
simd_f_t *csi1,
|
||||
float noise_estimate,
|
||||
float norm) {
|
||||
simd_cf_t _noise_estimate;
|
||||
simd_f_t _norm = srslte_simd_f_set1(norm);
|
||||
|
||||
_noise_estimate.re = srslte_simd_f_set1(noise_estimate);
|
||||
_noise_estimate.im = srslte_simd_f_zero();
|
||||
|
||||
/* 1. A = H' x H + No*/
|
||||
simd_cf_t a00 =
|
||||
srslte_simd_cf_add(srslte_simd_cf_add(srslte_simd_cf_conjprod(h00, h00), srslte_simd_cf_conjprod(h10, h10)),
|
||||
_noise_estimate);
|
||||
simd_cf_t a01 = srslte_simd_cf_add(srslte_simd_cf_conjprod(h01, h00), srslte_simd_cf_conjprod(h11, h10));
|
||||
simd_cf_t a10 = srslte_simd_cf_add(srslte_simd_cf_conjprod(h00, h01), srslte_simd_cf_conjprod(h10, h11));
|
||||
simd_cf_t a11 =
|
||||
srslte_simd_cf_add(srslte_simd_cf_add(srslte_simd_cf_conjprod(h01, h01), srslte_simd_cf_conjprod(h11, h11)),
|
||||
_noise_estimate);
|
||||
simd_cf_t a_det_rcp = srslte_simd_cf_rcp(srslte_mat_2x2_det_simd(a00, a01, a10, a11));
|
||||
|
||||
/* 2. B = inv(H' x H + No) = inv(A) */
|
||||
simd_cf_t _norm2 = srslte_simd_cf_mul(a_det_rcp, _norm);
|
||||
simd_cf_t b00 = srslte_simd_cf_prod(a11, _norm2);
|
||||
simd_cf_t b01 = srslte_simd_cf_prod(srslte_simd_cf_neg(a01), _norm2);
|
||||
simd_cf_t b10 = srslte_simd_cf_prod(srslte_simd_cf_neg(a10), _norm2);
|
||||
simd_cf_t b11 = srslte_simd_cf_prod(a00, _norm2);
|
||||
|
||||
|
||||
/* 3. W = inv(H' x H + No) x H' = B x H' */
|
||||
simd_cf_t w00 = srslte_simd_cf_add(srslte_simd_cf_conjprod(b00, h00), srslte_simd_cf_conjprod(b01, h01));
|
||||
simd_cf_t w01 = srslte_simd_cf_add(srslte_simd_cf_conjprod(b00, h10), srslte_simd_cf_conjprod(b01, h11));
|
||||
simd_cf_t w10 = srslte_simd_cf_add(srslte_simd_cf_conjprod(b10, h00), srslte_simd_cf_conjprod(b11, h01));
|
||||
simd_cf_t w11 = srslte_simd_cf_add(srslte_simd_cf_conjprod(b10, h10), srslte_simd_cf_conjprod(b11, h11));
|
||||
|
||||
/* 4. X = W x Y */
|
||||
*x0 = srslte_simd_cf_add(srslte_simd_cf_prod(y0, w00), srslte_simd_cf_prod(y1, w01));
|
||||
*x1 = srslte_simd_cf_add(srslte_simd_cf_prod(y0, w10), srslte_simd_cf_prod(y1, w11));
|
||||
|
||||
/* 5. Extract CSI */
|
||||
*csi0 = srslte_simd_f_rcp(srslte_simd_cf_re(b00));
|
||||
*csi1 = srslte_simd_f_rcp(srslte_simd_cf_re(b11));
|
||||
}
|
||||
|
||||
static inline void srslte_mat_2x2_mmse_simd(simd_cf_t y0,
|
||||
simd_cf_t y1,
|
||||
simd_cf_t h00,
|
||||
simd_cf_t h01,
|
||||
simd_cf_t h10,
|
||||
simd_cf_t h11,
|
||||
simd_cf_t *x0,
|
||||
simd_cf_t *x1,
|
||||
float noise_estimate,
|
||||
float norm) {
|
||||
simd_f_t csi0, csi1;
|
||||
srslte_mat_2x2_mmse_csi_simd(y0, y1, h00, h01, h10, h11, x0, x1, &csi0, &csi1, noise_estimate, norm);
|
||||
}
|
||||
|
||||
#endif /* SRSLTE_SIMD_CF_SIZE != 0 */
|
||||
#endif /* SRSLTE_MAT_H */
|
||||
|
|
|
@ -197,7 +197,7 @@ static inline simd_f_t srslte_simd_f_loadu(const float *ptr) {
|
|||
#ifdef LV_HAVE_AVX512
|
||||
return _mm512_loadu_ps(ptr);
|
||||
#else /* LV_HAVE_AVX512 */
|
||||
#ifdef LV_HAVE_AVX2
|
||||
#ifdef LV_HAVE_AVX2
|
||||
return _mm256_loadu_ps(ptr);
|
||||
#else /* LV_HAVE_AVX2 */
|
||||
#ifdef LV_HAVE_SSE
|
||||
|
@ -233,7 +233,7 @@ static inline void srslte_simd_f_storeu(float *ptr, simd_f_t simdreg) {
|
|||
#ifdef LV_HAVE_AVX512
|
||||
_mm512_storeu_ps(ptr, simdreg);
|
||||
#else /* LV_HAVE_AVX512 */
|
||||
#ifdef LV_HAVE_AVX2
|
||||
#ifdef LV_HAVE_AVX2
|
||||
_mm256_storeu_ps(ptr, simdreg);
|
||||
#else /* LV_HAVE_AVX2 */
|
||||
#ifdef LV_HAVE_SSE
|
||||
|
@ -360,7 +360,7 @@ static inline simd_f_t srslte_simd_f_add(simd_f_t a, simd_f_t b) {
|
|||
#ifdef LV_HAVE_AVX2
|
||||
return _mm256_add_ps(a, b);
|
||||
#else /* LV_HAVE_AVX2 */
|
||||
#ifdef LV_HAVE_SSE
|
||||
#ifdef LV_HAVE_SSE
|
||||
return _mm_add_ps(a, b);
|
||||
#else /* LV_HAVE_SSE */
|
||||
#ifdef HAVE_NEON
|
||||
|
@ -376,9 +376,9 @@ static inline simd_f_t srslte_simd_f_zero (void) {
|
|||
return _mm512_setzero_ps();
|
||||
#else /* LV_HAVE_AVX512 */
|
||||
#ifdef LV_HAVE_AVX2
|
||||
return _mm256_setzero_ps();
|
||||
return _mm256_setzero_ps();
|
||||
#else /* LV_HAVE_AVX2 */
|
||||
#ifdef LV_HAVE_SSE
|
||||
#ifdef LV_HAVE_SSE
|
||||
return _mm_setzero_ps();
|
||||
#else /* LV_HAVE_SSE */
|
||||
#ifdef HAVE_NEON
|
||||
|
@ -401,7 +401,7 @@ static inline simd_f_t srslte_simd_f_swap(simd_f_t a) {
|
|||
#else /* LV_HAVE_SSE */
|
||||
#ifdef HAVE_NEON
|
||||
return vcombine_f32(vrev64_f32(vget_low_f32(a)), vrev64_f32(vget_high_f32(a)));
|
||||
#endif /* HAVE_NEON */
|
||||
#endif /* HAVE_NEON */
|
||||
#endif /* LV_HAVE_SSE */
|
||||
#endif /* LV_HAVE_AVX2 */
|
||||
#endif /* LV_HAVE_AVX512 */
|
||||
|
@ -443,7 +443,7 @@ static inline simd_f_t srslte_simd_f_sqrt(simd_f_t a) {
|
|||
#ifdef LV_HAVE_AVX512
|
||||
return _mm512_sqrt_ps(a);
|
||||
#else /* LV_HAVE_AVX512 */
|
||||
#ifdef LV_HAVE_AVX2
|
||||
#ifdef LV_HAVE_AVX2
|
||||
return _mm256_sqrt_ps(a);
|
||||
#else /* LV_HAVE_AVX2 */
|
||||
#ifdef LV_HAVE_SSE
|
||||
|
@ -458,7 +458,43 @@ static inline simd_f_t srslte_simd_f_sqrt(simd_f_t a) {
|
|||
float32x4_t zeros = vmovq_n_f32(0); /* Zero vector */
|
||||
uint32x4_t mask = vceqq_f32(a, zeros); /* Zero vector mask */
|
||||
return vbslq_f32(mask, zeros, result); /* Force zero results and return */
|
||||
#endif /* HAVE_NEON */
|
||||
#endif /* HAVE_NEON */
|
||||
#endif /* LV_HAVE_SSE */
|
||||
#endif /* LV_HAVE_AVX2 */
|
||||
#endif /* LV_HAVE_AVX512 */
|
||||
}
|
||||
|
||||
static inline simd_f_t srslte_simd_f_neg(simd_f_t a) {
|
||||
#ifdef LV_HAVE_AVX512
|
||||
return _mm512_xor_ps(_mm512_set1_ps(-0.0f), a);
|
||||
#else /* LV_HAVE_AVX512 */
|
||||
#ifdef LV_HAVE_AVX2
|
||||
return _mm256_xor_ps(_mm256_set1_ps(-0.0f), a);
|
||||
#else /* LV_HAVE_AVX2 */
|
||||
#ifdef LV_HAVE_SSE
|
||||
return _mm_xor_ps(_mm_set1_ps(-0.0f), a);
|
||||
#else /* LV_HAVE_SSE */
|
||||
#ifdef HAVE_NEON
|
||||
return vnegq_f32(a);
|
||||
#endif /* HAVE_NEON */
|
||||
#endif /* LV_HAVE_SSE */
|
||||
#endif /* LV_HAVE_AVX2 */
|
||||
#endif /* LV_HAVE_AVX512 */
|
||||
}
|
||||
|
||||
static inline simd_f_t srslte_simd_f_neg_mask(simd_f_t a, simd_f_t mask) {
|
||||
#ifdef LV_HAVE_AVX512
|
||||
return _mm512_xor_ps(mask, a);
|
||||
#else /* LV_HAVE_AVX512 */
|
||||
#ifdef LV_HAVE_AVX2
|
||||
return _mm256_xor_ps(mask, a);
|
||||
#else /* LV_HAVE_AVX2 */
|
||||
#ifdef LV_HAVE_SSE
|
||||
return _mm_xor_ps(mask, a);
|
||||
#else /* LV_HAVE_SSE */
|
||||
#ifdef HAVE_NEON
|
||||
return (float32x4_t) veorq_s32((int32x4_t) a, (int32x4_t) mask);
|
||||
#endif /* HAVE_NEON */
|
||||
#endif /* LV_HAVE_SSE */
|
||||
#endif /* LV_HAVE_AVX2 */
|
||||
#endif /* LV_HAVE_AVX512 */
|
||||
|
@ -470,12 +506,11 @@ static inline simd_f_t srslte_simd_f_sqrt(simd_f_t a) {
|
|||
#if SRSLTE_SIMD_CF_SIZE
|
||||
|
||||
#ifdef HAVE_NEON
|
||||
typedef float32x4x2_t simd_cf_t;
|
||||
typedef float32x4x2_t simd_cf_t;
|
||||
#else
|
||||
typedef struct {
|
||||
simd_f_t re;
|
||||
simd_f_t im;
|
||||
|
||||
} simd_cf_t;
|
||||
#endif
|
||||
|
||||
|
@ -667,8 +702,8 @@ static inline void srslte_simd_cf_store(float *re, float *im, simd_cf_t simdreg)
|
|||
_mm512_store_ps(im, simdreg.im);
|
||||
#else /* LV_HAVE_AVX512 */
|
||||
#ifdef LV_HAVE_AVX2
|
||||
_mm256_store_ps((float *) re, simdreg.re);
|
||||
_mm256_store_ps((float *) im, simdreg.im);
|
||||
_mm256_store_ps(re, simdreg.re);
|
||||
_mm256_store_ps(im, simdreg.im);
|
||||
#else /* LV_HAVE_AVX512 */
|
||||
#ifdef LV_HAVE_SSE
|
||||
_mm_store_ps((float *) re, simdreg.re);
|
||||
|
@ -689,8 +724,8 @@ static inline void srslte_simd_cf_storeu(float *re, float *im, simd_cf_t simdreg
|
|||
_mm512_storeu_ps(im, simdreg.im);
|
||||
#else /* LV_HAVE_AVX512 */
|
||||
#ifdef LV_HAVE_AVX2
|
||||
_mm256_storeu_ps((float *) re, simdreg.re);
|
||||
_mm256_storeu_ps((float *) im, simdreg.im);
|
||||
_mm256_storeu_ps(re, simdreg.re);
|
||||
_mm256_storeu_ps(im, simdreg.im);
|
||||
#else /* LV_HAVE_AVX512 */
|
||||
#ifdef LV_HAVE_SSE
|
||||
_mm_storeu_ps((float *) re, simdreg.re);
|
||||
|
@ -754,10 +789,15 @@ static inline simd_cf_t srslte_simd_cf_prod (simd_cf_t a, simd_cf_t b) {
|
|||
_mm512_mul_ps(a.im, b.re));
|
||||
#else /* LV_HAVE_AVX512 */
|
||||
#ifdef LV_HAVE_AVX2
|
||||
#ifdef LV_HAVE_FMA
|
||||
ret.re = _mm256_fmsub_ps(a.re, b.re, _mm256_mul_ps(a.im, b.im));
|
||||
ret.im = _mm256_fmadd_ps(a.re, b.im, _mm256_mul_ps(a.im, b.re));
|
||||
#else /* LV_HAVE_FMA */
|
||||
ret.re = _mm256_sub_ps(_mm256_mul_ps(a.re, b.re),
|
||||
_mm256_mul_ps(a.im, b.im));
|
||||
ret.im = _mm256_add_ps(_mm256_mul_ps(a.re, b.im),
|
||||
_mm256_mul_ps(a.im, b.re));
|
||||
#endif /* LV_HAVE_FMA */
|
||||
#else
|
||||
#ifdef LV_HAVE_SSE
|
||||
ret.re = _mm_sub_ps(_mm_mul_ps(a.re, b.re),
|
||||
|
@ -833,8 +873,32 @@ static inline simd_cf_t srslte_simd_cf_add (simd_cf_t a, simd_cf_t b) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline simd_cf_t srslte_simd_cf_sub (simd_cf_t a, simd_cf_t b) {
|
||||
simd_cf_t ret;
|
||||
#ifdef LV_HAVE_AVX512
|
||||
ret.re = _mm512_sub_ps(a.re, b.re);
|
||||
ret.im = _mm512_sub_ps(a.im, b.im);
|
||||
#else /* LV_HAVE_AVX512 */
|
||||
#ifdef LV_HAVE_AVX2
|
||||
ret.re = _mm256_sub_ps(a.re, b.re);
|
||||
ret.im = _mm256_sub_ps(a.im, b.im);
|
||||
#else /* LV_HAVE_AVX2 */
|
||||
#ifdef LV_HAVE_SSE
|
||||
ret.re = _mm_sub_ps(a.re, b.re);
|
||||
ret.im = _mm_sub_ps(a.im, b.im);
|
||||
#else /* LV_HAVE_SSE */
|
||||
#ifdef HAVE_NEON
|
||||
ret.val[0] = vsubq_f32(a.val[0],b.val[0]);
|
||||
ret.val[1] = vsubq_f32(a.val[1],b.val[1]);
|
||||
#endif /* HAVE_NEON */
|
||||
#endif /* LV_HAVE_SSE */
|
||||
#endif /* LV_HAVE_AVX2 */
|
||||
#endif /* LV_HAVE_AVX512 */
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline simd_cf_t srslte_simd_cf_mul (simd_cf_t a, simd_f_t b) {
|
||||
simd_cf_t ret;
|
||||
simd_cf_t ret;
|
||||
#ifdef LV_HAVE_AVX512
|
||||
ret.re = _mm512_mul_ps(a.re, b);
|
||||
ret.im = _mm512_mul_ps(a.im, b);
|
||||
|
@ -855,7 +919,7 @@ static inline simd_cf_t srslte_simd_cf_mul (simd_cf_t a, simd_f_t b) {
|
|||
#endif /* LV_HAVE_SSE */
|
||||
#endif /* LV_HAVE_AVX2 */
|
||||
#endif /* LV_HAVE_AVX512 */
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline simd_cf_t srslte_simd_cf_rcp (simd_cf_t a) {
|
||||
|
@ -902,6 +966,59 @@ static inline simd_cf_t srslte_simd_cf_rcp (simd_cf_t a) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline simd_cf_t srslte_simd_cf_neg (simd_cf_t a) {
|
||||
simd_cf_t ret;
|
||||
#if LV_HAVE_NEON
|
||||
ret.val[0] = srslte_simd_f_neg(a.val[0]);
|
||||
ret.val[1] = srslte_simd_f_neg(a.val[1]);
|
||||
#else /* LV_HAVE_NEON */
|
||||
ret.re = srslte_simd_f_neg(a.re);
|
||||
ret.im = srslte_simd_f_neg(a.im);
|
||||
#endif /* LV_HAVE_NEON */
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline simd_cf_t srslte_simd_cf_neg_mask (simd_cf_t a, simd_f_t mask) {
|
||||
simd_cf_t ret;
|
||||
#ifndef LV_HAVE_AVX512
|
||||
#ifdef LV_HAVE_AVX2
|
||||
mask = _mm256_permutevar8x32_ps(mask, _mm256_setr_epi32(0,4,1,5,2,6,3,7));
|
||||
#endif /* LV_HAVE_AVX2 */
|
||||
#endif /* LV_HAVE_AVX512 */
|
||||
#if LV_HAVE_NEON
|
||||
ret.val[0] = srslte_simd_f_neg_mask(a.val[0], mask);
|
||||
ret.val[1] = srslte_simd_f_neg_mask(a.val[1], mask);
|
||||
#else /* LV_HAVE_NEON */
|
||||
ret.re = srslte_simd_f_neg_mask(a.re, mask);
|
||||
ret.im = srslte_simd_f_neg_mask(a.im, mask);
|
||||
#endif /* LV_HAVE_NEON */
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline simd_cf_t srslte_simd_cf_conj (simd_cf_t a) {
|
||||
simd_cf_t ret;
|
||||
#if LV_HAVE_NEON
|
||||
ret.val[0] = a.val[0];
|
||||
ret.val[1] = srslte_simd_f_neg(a.val[1]);
|
||||
#else /* LV_HAVE_NEON */
|
||||
ret.re = a.re;
|
||||
ret.im = srslte_simd_f_neg(a.im);
|
||||
#endif /* LV_HAVE_NEON */
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline simd_cf_t srslte_simd_cf_mulj (simd_cf_t a) {
|
||||
simd_cf_t ret;
|
||||
#if LV_HAVE_NEON
|
||||
ret.val[0] = srslte_simd_f_neg(a.val[1]);
|
||||
ret.val[1] = a.val[0];
|
||||
#else /* LV_HAVE_NEON */
|
||||
ret.re = srslte_simd_f_neg(a.im);
|
||||
ret.im = a.re;
|
||||
#endif /* LV_HAVE_NEON */
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline simd_cf_t srslte_simd_cf_zero (void) {
|
||||
simd_cf_t ret;
|
||||
#ifdef LV_HAVE_AVX512
|
||||
|
@ -1057,7 +1174,7 @@ static inline simd_i_t srslte_simd_i_select(simd_i_t a, simd_i_t b, simd_sel_t s
|
|||
int* sel = (int*) &selector;
|
||||
int* c_ptr = (int*) &ret;
|
||||
for(int i = 0;i<4;i++)
|
||||
{
|
||||
{
|
||||
if(sel[i] == -1){
|
||||
c_ptr[i] = b_ptr[i];
|
||||
}else{
|
||||
|
@ -1115,7 +1232,7 @@ static inline simd_s_t srslte_simd_s_loadu(const int16_t *ptr) {
|
|||
#ifdef LV_HAVE_AVX512
|
||||
return _mm512_loadu_si512(ptr);
|
||||
#else /* LV_HAVE_AVX512 */
|
||||
#ifdef LV_HAVE_AVX2
|
||||
#ifdef LV_HAVE_AVX2
|
||||
return _mm256_loadu_si256((__m256i*) ptr);
|
||||
#else /* LV_HAVE_AVX2 */
|
||||
#ifdef LV_HAVE_SSE
|
||||
|
|
|
@ -99,6 +99,7 @@ SRSLTE_API void srslte_vec_convert_fi(const float *x, const float scale, int16_t
|
|||
SRSLTE_API void srslte_vec_convert_if(const int16_t *x, const float scale, float *z, const uint32_t len);
|
||||
|
||||
SRSLTE_API void srslte_vec_lut_sss(const short *x, const unsigned short *lut, short *y, const uint32_t len);
|
||||
SRSLTE_API void srslte_vec_lut_sis(const short *x, const unsigned int *lut, short *y, const uint32_t len);
|
||||
|
||||
/* vector product (element-wise) */
|
||||
SRSLTE_API void srslte_vec_prod_ccc(const cf_t *x, const cf_t *y, cf_t *z, const uint32_t len);
|
||||
|
@ -155,6 +156,9 @@ SRSLTE_API void srslte_vec_interleave(const cf_t *x, const cf_t *y, cf_t *z, con
|
|||
|
||||
SRSLTE_API void srslte_vec_interleave_add(const cf_t *x, const cf_t *y, cf_t *z, const int len);
|
||||
|
||||
SRSLTE_API void srslte_vec_apply_cfo(const cf_t *x, float cfo, cf_t *z, int len);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -130,6 +130,9 @@ SRSLTE_API void srslte_vec_interleave_simd(const cf_t *x, const cf_t *y, cf_t *z
|
|||
|
||||
SRSLTE_API void srslte_vec_interleave_add_simd(const cf_t *x, const cf_t *y, cf_t *z, const int len);
|
||||
|
||||
SRSLTE_API void srslte_vec_apply_cfo_simd(const cf_t *x, float cfo, cf_t *z, int len);
|
||||
|
||||
|
||||
/* SIMD Find Max functions */
|
||||
SRSLTE_API uint32_t srslte_vec_max_fi_simd(const float *x, const int len);
|
||||
|
||||
|
|
|
@ -34,150 +34,153 @@
|
|||
#define SRSLTE_RADIO_H
|
||||
|
||||
typedef struct {
|
||||
float tx_corr_dc_gain;
|
||||
float tx_corr_dc_phase;
|
||||
float tx_corr_iq_i;
|
||||
float tx_corr_iq_q;
|
||||
float rx_corr_dc_gain;
|
||||
float rx_corr_dc_phase;
|
||||
float rx_corr_iq_i;
|
||||
float rx_corr_iq_q;
|
||||
}rf_cal_t;
|
||||
|
||||
float tx_corr_dc_gain;
|
||||
float tx_corr_dc_phase;
|
||||
float tx_corr_iq_i;
|
||||
float tx_corr_iq_q;
|
||||
float rx_corr_dc_gain;
|
||||
float rx_corr_dc_phase;
|
||||
float rx_corr_iq_i;
|
||||
float rx_corr_iq_q;
|
||||
} rf_cal_t;
|
||||
|
||||
namespace srslte {
|
||||
|
||||
|
||||
/* Interface to the RF frontend.
|
||||
*/
|
||||
class radio
|
||||
{
|
||||
public:
|
||||
radio() : tr_local_time(1024*10), tr_usrp_time(1024*10), tr_tx_time(1024*10), tr_is_eob(1024*10) {
|
||||
bzero(&rf_device, sizeof(srslte_rf_t));
|
||||
bzero(&end_of_burst_time, sizeof(srslte_timestamp_t));
|
||||
bzero(zeros, burst_preamble_max_samples*sizeof(cf_t));
|
||||
|
||||
burst_preamble_sec = 0;
|
||||
is_start_of_burst = false;
|
||||
burst_preamble_samples = 0;
|
||||
burst_preamble_time_rounded = 0;
|
||||
|
||||
cur_tx_srate = 0;
|
||||
tx_adv_sec = 0;
|
||||
tx_adv_nsamples = 0;
|
||||
tx_adv_auto = false;
|
||||
tx_adv_negative = false;
|
||||
tx_freq = 0;
|
||||
rx_freq = 0;
|
||||
trace_enabled = false;
|
||||
tti = 0;
|
||||
agc_enabled = false;
|
||||
radio_is_streaming = false;
|
||||
is_initialized = false;
|
||||
};
|
||||
|
||||
bool init(char *args = NULL, char *devname = NULL, uint32_t nof_channels = 1);
|
||||
void stop();
|
||||
void reset();
|
||||
bool start_agc(bool tx_gain_same_rx);
|
||||
|
||||
void set_burst_preamble(double preamble_us);
|
||||
void set_tx_adv(int nsamples);
|
||||
void set_tx_adv_neg(bool tx_adv_is_neg);
|
||||
|
||||
void set_manual_calibration(rf_cal_t *calibration);
|
||||
|
||||
void get_time(srslte_timestamp_t *now);
|
||||
bool tx_single(void *buffer, uint32_t nof_samples, srslte_timestamp_t tx_time);
|
||||
bool tx(void *buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, srslte_timestamp_t tx_time);
|
||||
void tx_end();
|
||||
bool rx_now(void *buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, srslte_timestamp_t *rxd_time);
|
||||
bool rx_at(void *buffer, uint32_t nof_samples, srslte_timestamp_t rx_time);
|
||||
class radio {
|
||||
public:
|
||||
radio() : tr_local_time(1024 * 10), tr_usrp_time(1024 * 10), tr_tx_time(1024 * 10), tr_is_eob(1024 * 10) {
|
||||
bzero(&rf_device, sizeof(srslte_rf_t));
|
||||
bzero(&end_of_burst_time, sizeof(srslte_timestamp_t));
|
||||
bzero(zeros, burst_preamble_max_samples * sizeof(cf_t));
|
||||
|
||||
void set_tx_gain(float gain);
|
||||
void set_rx_gain(float gain);
|
||||
void set_tx_rx_gain_offset(float offset);
|
||||
double set_rx_gain_th(float gain);
|
||||
burst_preamble_sec = 0;
|
||||
is_start_of_burst = false;
|
||||
burst_preamble_samples = 0;
|
||||
burst_preamble_time_rounded = 0;
|
||||
|
||||
void set_freq_offset(double freq);
|
||||
void set_tx_freq(double freq);
|
||||
void set_rx_freq(double freq);
|
||||
cur_tx_srate = 0;
|
||||
tx_adv_sec = 0;
|
||||
tx_adv_nsamples = 0;
|
||||
tx_adv_auto = false;
|
||||
tx_adv_negative = false;
|
||||
tx_freq = 0;
|
||||
rx_freq = 0;
|
||||
trace_enabled = false;
|
||||
tti = 0;
|
||||
agc_enabled = false;
|
||||
radio_is_streaming = false;
|
||||
is_initialized = false;
|
||||
continuous_tx = false;
|
||||
};
|
||||
|
||||
double get_freq_offset();
|
||||
double get_tx_freq();
|
||||
double get_rx_freq();
|
||||
bool init(char *args = NULL, char *devname = NULL, uint32_t nof_channels = 1);
|
||||
void stop();
|
||||
void reset();
|
||||
bool start_agc(bool tx_gain_same_rx);
|
||||
|
||||
void set_master_clock_rate(double rate);
|
||||
void set_tx_srate(double srate);
|
||||
void set_rx_srate(double srate);
|
||||
void set_burst_preamble(double preamble_us);
|
||||
void set_tx_adv(int nsamples);
|
||||
void set_tx_adv_neg(bool tx_adv_is_neg);
|
||||
|
||||
float get_tx_gain();
|
||||
float get_rx_gain();
|
||||
|
||||
float get_max_tx_power();
|
||||
float set_tx_power(float power);
|
||||
float get_rssi();
|
||||
bool has_rssi();
|
||||
|
||||
void start_trace();
|
||||
void write_trace(std::string filename);
|
||||
void set_manual_calibration(rf_cal_t *calibration);
|
||||
|
||||
void set_tti(uint32_t tti);
|
||||
bool is_continuous_tx();
|
||||
void set_continuous_tx(bool enable);
|
||||
|
||||
bool is_first_of_burst();
|
||||
void get_time(srslte_timestamp_t *now);
|
||||
bool tx_single(void *buffer, uint32_t nof_samples, srslte_timestamp_t tx_time);
|
||||
bool tx(void *buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, srslte_timestamp_t tx_time);
|
||||
void tx_end();
|
||||
bool rx_now(void *buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, srslte_timestamp_t *rxd_time);
|
||||
bool rx_at(void *buffer, uint32_t nof_samples, srslte_timestamp_t rx_time);
|
||||
|
||||
bool is_init();
|
||||
void set_tx_gain(float gain);
|
||||
void set_rx_gain(float gain);
|
||||
void set_tx_rx_gain_offset(float offset);
|
||||
double set_rx_gain_th(float gain);
|
||||
|
||||
void register_error_handler(srslte_rf_error_handler_t h);
|
||||
|
||||
protected:
|
||||
|
||||
void save_trace(uint32_t is_eob, srslte_timestamp_t *usrp_time);
|
||||
|
||||
srslte_rf_t rf_device;
|
||||
|
||||
|
||||
const static uint32_t burst_preamble_max_samples = 30720000; // 30.72 MHz is maximum frequency
|
||||
double burst_preamble_sec;// Start of burst preamble time (off->on RF transition time)
|
||||
srslte_timestamp_t end_of_burst_time;
|
||||
bool is_start_of_burst;
|
||||
uint32_t burst_preamble_samples;
|
||||
double burst_preamble_time_rounded; // preamble time rounded to sample time
|
||||
cf_t zeros[burst_preamble_max_samples];
|
||||
double cur_tx_srate;
|
||||
void set_freq_offset(double freq);
|
||||
void set_tx_freq(double freq);
|
||||
void set_rx_freq(double freq);
|
||||
|
||||
double tx_adv_sec; // Transmission time advance to compensate for antenna->timestamp delay
|
||||
int tx_adv_nsamples; // Transmision time advance in number of samples
|
||||
|
||||
// Define default values for known radios
|
||||
bool tx_adv_auto;
|
||||
bool tx_adv_negative;
|
||||
const static double uhd_default_burst_preamble_sec = 600*1e-6;
|
||||
const static double uhd_default_tx_adv_samples = 98;
|
||||
const static double uhd_default_tx_adv_offset_sec = 4*1e-6;
|
||||
|
||||
const static double blade_default_burst_preamble_sec = 0.0;
|
||||
const static double blade_default_tx_adv_samples = 27;
|
||||
const static double blade_default_tx_adv_offset_sec = 1e-6;
|
||||
double get_freq_offset();
|
||||
double get_tx_freq();
|
||||
double get_rx_freq();
|
||||
|
||||
double tx_freq, rx_freq, freq_offset;
|
||||
|
||||
trace<uint32_t> tr_local_time;
|
||||
trace<uint32_t> tr_usrp_time;
|
||||
trace<uint32_t> tr_tx_time;
|
||||
trace<uint32_t> tr_is_eob;
|
||||
bool trace_enabled;
|
||||
uint32_t tti;
|
||||
bool agc_enabled;
|
||||
void set_master_clock_rate(double rate);
|
||||
void set_tx_srate(double srate);
|
||||
void set_rx_srate(double srate);
|
||||
|
||||
bool is_initialized = true;;
|
||||
bool radio_is_streaming;
|
||||
float get_tx_gain();
|
||||
float get_rx_gain();
|
||||
srslte_rf_info_t *get_info();
|
||||
|
||||
uint32_t saved_nof_channels;
|
||||
char saved_args[128];
|
||||
char saved_devname[128];
|
||||
float get_max_tx_power();
|
||||
float set_tx_power(float power);
|
||||
float get_rssi();
|
||||
bool has_rssi();
|
||||
|
||||
};
|
||||
void start_trace();
|
||||
void write_trace(std::string filename);
|
||||
|
||||
void set_tti(uint32_t tti);
|
||||
|
||||
bool is_first_of_burst();
|
||||
|
||||
bool is_init();
|
||||
|
||||
void register_error_handler(srslte_rf_error_handler_t h);
|
||||
|
||||
protected:
|
||||
|
||||
void save_trace(uint32_t is_eob, srslte_timestamp_t *usrp_time);
|
||||
|
||||
srslte_rf_t rf_device;
|
||||
|
||||
const static uint32_t burst_preamble_max_samples = 30720000; // 30.72 MHz is maximum frequency
|
||||
double burst_preamble_sec;// Start of burst preamble time (off->on RF transition time)
|
||||
srslte_timestamp_t end_of_burst_time;
|
||||
bool is_start_of_burst;
|
||||
uint32_t burst_preamble_samples;
|
||||
double burst_preamble_time_rounded; // preamble time rounded to sample time
|
||||
cf_t zeros[burst_preamble_max_samples];
|
||||
double cur_tx_srate;
|
||||
|
||||
double tx_adv_sec; // Transmission time advance to compensate for antenna->timestamp delay
|
||||
int tx_adv_nsamples; // Transmision time advance in number of samples
|
||||
|
||||
// Define default values for known radios
|
||||
bool tx_adv_auto;
|
||||
bool tx_adv_negative;
|
||||
const static double uhd_default_burst_preamble_sec = 600 * 1e-6;
|
||||
const static double uhd_default_tx_adv_samples = 98;
|
||||
const static double uhd_default_tx_adv_offset_sec = 4 * 1e-6;
|
||||
|
||||
const static double blade_default_burst_preamble_sec = 0.0;
|
||||
const static double blade_default_tx_adv_samples = 27;
|
||||
const static double blade_default_tx_adv_offset_sec = 1e-6;
|
||||
|
||||
double tx_freq, rx_freq, freq_offset;
|
||||
|
||||
trace<uint32_t> tr_local_time;
|
||||
trace<uint32_t> tr_usrp_time;
|
||||
trace<uint32_t> tr_tx_time;
|
||||
trace<uint32_t> tr_is_eob;
|
||||
bool trace_enabled;
|
||||
uint32_t tti;
|
||||
bool agc_enabled;
|
||||
|
||||
bool continuous_tx;
|
||||
bool is_initialized;
|
||||
bool radio_is_streaming;
|
||||
|
||||
uint32_t saved_nof_channels;
|
||||
char saved_args[128];
|
||||
char saved_devname[128];
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SRSLTE_RADIO_H
|
||||
|
|
|
@ -45,7 +45,8 @@ namespace srslte {
|
|||
class radio_multi : public radio
|
||||
{
|
||||
public:
|
||||
|
||||
radio_multi() {}
|
||||
~radio_multi() {}
|
||||
bool init_multi(uint32_t nof_rx_antennas, char *args = NULL, char *devname = NULL);
|
||||
bool rx_now(cf_t *buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, srslte_timestamp_t *rxd_time);
|
||||
};
|
||||
|
|
|
@ -57,7 +57,9 @@ public:
|
|||
void reestablish();
|
||||
void reset();
|
||||
void write_sdu(uint32_t lcid, byte_buffer_t *sdu);
|
||||
void write_sdu_mch(uint32_t lcid, byte_buffer_t *sdu);
|
||||
void add_bearer(uint32_t lcid, srslte_pdcp_config_t cnfg = srslte_pdcp_config_t());
|
||||
void add_bearer_mrb(uint32_t lcid, srslte_pdcp_config_t cnfg = srslte_pdcp_config_t());
|
||||
void config_security(uint32_t lcid,
|
||||
uint8_t *k_enc,
|
||||
uint8_t *k_int,
|
||||
|
@ -72,9 +74,11 @@ public:
|
|||
|
||||
// RLC interface
|
||||
void write_pdu(uint32_t lcid, byte_buffer_t *sdu);
|
||||
void write_pdu_mch(uint32_t lcid, byte_buffer_t *sdu);
|
||||
void write_pdu_bcch_bch(byte_buffer_t *sdu);
|
||||
void write_pdu_bcch_dlsch(byte_buffer_t *sdu);
|
||||
void write_pdu_pcch(byte_buffer_t *sdu);
|
||||
|
||||
|
||||
private:
|
||||
srsue::rlc_interface_pdcp *rlc;
|
||||
|
@ -83,10 +87,12 @@ private:
|
|||
|
||||
log *pdcp_log;
|
||||
pdcp_entity pdcp_array[SRSLTE_N_RADIO_BEARERS];
|
||||
pdcp_entity pdcp_array_mrb[SRSLTE_N_MCH_LCIDS];
|
||||
uint32_t lcid; // default LCID that is maintained active by PDCP instance
|
||||
uint8_t direction;
|
||||
|
||||
bool valid_lcid(uint32_t lcid);
|
||||
bool valid_mch_lcid(uint32_t lcid);
|
||||
};
|
||||
|
||||
} // namespace srslte
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "srslte/common/common.h"
|
||||
#include "srslte/interfaces/ue_interfaces.h"
|
||||
#include "srslte/common/security.h"
|
||||
#include "srslte/common/msg_queue.h"
|
||||
#include "srslte/common/threads.h"
|
||||
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include "srslte/common/log.h"
|
||||
#include "srslte/common/common.h"
|
||||
#include "srslte/interfaces/ue_interfaces.h"
|
||||
#include "srslte/common/msg_queue.h"
|
||||
#include "srslte/upper/rlc_entity.h"
|
||||
#include "srslte/upper/rlc_metrics.h"
|
||||
#include "srslte/upper/rlc_common.h"
|
||||
|
@ -64,17 +63,21 @@ public:
|
|||
|
||||
// PDCP interface
|
||||
void write_sdu(uint32_t lcid, byte_buffer_t *sdu);
|
||||
|
||||
void write_sdu_mch(uint32_t lcid, byte_buffer_t *sdu);
|
||||
bool rb_is_um(uint32_t lcid);
|
||||
|
||||
// MAC interface
|
||||
uint32_t get_buffer_state(uint32_t lcid);
|
||||
uint32_t get_total_buffer_state(uint32_t lcid);
|
||||
uint32_t get_total_mch_buffer_state(uint32_t lcid);
|
||||
int read_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes);
|
||||
int read_pdu_mch(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes);
|
||||
int get_increment_sequence_num();
|
||||
void write_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes);
|
||||
void write_pdu_bcch_bch(uint8_t *payload, uint32_t nof_bytes);
|
||||
void write_pdu_bcch_dlsch(uint8_t *payload, uint32_t nof_bytes);
|
||||
void write_pdu_pcch(uint8_t *payload, uint32_t nof_bytes);
|
||||
void write_pdu_mch(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes);
|
||||
|
||||
// RRC interface
|
||||
void reestablish();
|
||||
|
@ -82,7 +85,8 @@ public:
|
|||
void empty_queue();
|
||||
void add_bearer(uint32_t lcid);
|
||||
void add_bearer(uint32_t lcid, srslte_rlc_config_t cnfg);
|
||||
|
||||
void add_bearer_mrb(uint32_t lcid);
|
||||
void add_bearer_mrb_enb(uint32_t lcid);
|
||||
private:
|
||||
void reset_metrics();
|
||||
|
||||
|
@ -93,13 +97,16 @@ private:
|
|||
srslte::mac_interface_timers *mac_timers;
|
||||
srsue::ue_interface *ue;
|
||||
srslte::rlc_entity rlc_array[SRSLTE_N_RADIO_BEARERS];
|
||||
srslte::rlc_um rlc_array_mrb[SRSLTE_N_MCH_LCIDS];
|
||||
uint32_t default_lcid;
|
||||
|
||||
long ul_tput_bytes[SRSLTE_N_RADIO_BEARERS];
|
||||
long dl_tput_bytes[SRSLTE_N_RADIO_BEARERS];
|
||||
long dl_tput_bytes_mrb[SRSLTE_N_MCH_LCIDS];
|
||||
struct timeval metrics_time[3];
|
||||
|
||||
bool valid_lcid(uint32_t lcid);
|
||||
bool valid_lcid_mrb(uint32_t lcid);
|
||||
};
|
||||
|
||||
} // namespace srsue
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include "srslte/common/log.h"
|
||||
#include "srslte/common/common.h"
|
||||
#include "srslte/interfaces/ue_interfaces.h"
|
||||
#include "srslte/common/msg_queue.h"
|
||||
#include "srslte/upper/rlc_tx_queue.h"
|
||||
#include "srslte/common/timeout.h"
|
||||
#include "srslte/upper/rlc_common.h"
|
||||
#include <map>
|
||||
|
@ -104,7 +104,7 @@ private:
|
|||
srsue::rrc_interface_rlc *rrc;
|
||||
|
||||
// TX SDU buffers
|
||||
msg_queue tx_sdu_queue;
|
||||
rlc_tx_queue tx_sdu_queue;
|
||||
byte_buffer_t *tx_sdu;
|
||||
|
||||
// PDU being resegmented
|
||||
|
@ -217,8 +217,10 @@ bool rlc_am_is_control_pdu(byte_buffer_t *pdu);
|
|||
bool rlc_am_is_control_pdu(uint8_t *payload);
|
||||
bool rlc_am_is_pdu_segment(uint8_t *payload);
|
||||
std::string rlc_am_to_string(rlc_status_pdu_t *status);
|
||||
bool rlc_am_start_aligned(uint8_t fi);
|
||||
bool rlc_am_end_aligned(uint8_t fi);
|
||||
bool rlc_am_start_aligned(const uint8_t fi);
|
||||
bool rlc_am_end_aligned(const uint8_t fi);
|
||||
bool rlc_am_is_unaligned(const uint8_t fi);
|
||||
bool rlc_am_not_start_aligned(const uint8_t fi);
|
||||
|
||||
} // namespace srslte
|
||||
|
||||
|
|
|
@ -47,12 +47,12 @@ class rlc_entity
|
|||
{
|
||||
public:
|
||||
rlc_entity();
|
||||
void init(rlc_mode_t mode,
|
||||
log *rlc_entity_log_,
|
||||
uint32_t lcid_,
|
||||
srsue::pdcp_interface_rlc *pdcp_,
|
||||
srsue::rrc_interface_rlc *rrc_,
|
||||
mac_interface_timers *mac_timers_);
|
||||
void init(rlc_mode_t mode,
|
||||
log *rlc_entity_log_,
|
||||
uint32_t lcid_,
|
||||
srsue::pdcp_interface_rlc *pdcp_,
|
||||
srsue::rrc_interface_rlc *rrc_,
|
||||
mac_interface_timers *mac_timers_);
|
||||
|
||||
void configure(srslte_rlc_config_t cnfg);
|
||||
void reset();
|
||||
|
|
|
@ -73,6 +73,7 @@ typedef struct {
|
|||
uint32_t rx_window_size;
|
||||
uint32_t rx_mod; // Rx counter modulus
|
||||
uint32_t tx_mod; // Tx counter modulus
|
||||
bool is_mrb; // Whether this is a multicast bearer
|
||||
} srslte_rlc_um_config_t;
|
||||
|
||||
|
||||
|
@ -83,6 +84,9 @@ public:
|
|||
srslte_rlc_am_config_t am;
|
||||
srslte_rlc_um_config_t um;
|
||||
|
||||
// Default ctor
|
||||
srslte_rlc_config_t(): rlc_mode(LIBLTE_RRC_RLC_MODE_AM), am(), um() {};
|
||||
|
||||
// Constructor based on liblte's RLC config
|
||||
srslte_rlc_config_t(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) : rlc_mode(cnfg->rlc_mode), am(), um()
|
||||
{
|
||||
|
@ -119,6 +123,21 @@ public:
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Factory for MCH
|
||||
static srslte_rlc_config_t mch_config()
|
||||
{
|
||||
srslte_rlc_config_t cfg;
|
||||
cfg.rlc_mode = LIBLTE_RRC_RLC_MODE_UM_UNI_DL;
|
||||
cfg.um.t_reordering = 0;
|
||||
cfg.um.rx_sn_field_length = RLC_UMD_SN_SIZE_5_BITS;
|
||||
cfg.um.rx_window_size = 0;
|
||||
cfg.um.rx_mod = 1;
|
||||
cfg.um.tx_sn_field_length = RLC_UMD_SN_SIZE_5_BITS;
|
||||
cfg.um.tx_mod = 1;
|
||||
cfg.um.is_mrb = true;
|
||||
return cfg;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace srslte
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include "srslte/common/log.h"
|
||||
#include "srslte/common/common.h"
|
||||
#include "srslte/interfaces/ue_interfaces.h"
|
||||
#include "srslte/common/msg_queue.h"
|
||||
#include "srslte/upper/rlc_tx_queue.h"
|
||||
#include "srslte/upper/rlc_common.h"
|
||||
|
||||
namespace srslte {
|
||||
|
@ -41,11 +41,11 @@ class rlc_tm
|
|||
{
|
||||
public:
|
||||
rlc_tm();
|
||||
void init(log *rlc_entity_log_,
|
||||
uint32_t lcid_,
|
||||
srsue::pdcp_interface_rlc *pdcp_,
|
||||
srsue::rrc_interface_rlc *rrc_,
|
||||
mac_interface_timers *mac_timers);
|
||||
void init(log *rlc_entity_log_,
|
||||
uint32_t lcid_,
|
||||
srsue::pdcp_interface_rlc *pdcp_,
|
||||
srsue::rrc_interface_rlc *rrc_,
|
||||
mac_interface_timers *mac_timers);
|
||||
void configure(srslte_rlc_config_t cnfg);
|
||||
void reset();
|
||||
void stop();
|
||||
|
@ -72,7 +72,7 @@ private:
|
|||
srsue::rrc_interface_rlc *rrc;
|
||||
|
||||
// Thread-safe queues for MAC messages
|
||||
msg_queue ul_queue;
|
||||
rlc_tx_queue ul_queue;
|
||||
};
|
||||
|
||||
} // namespace srsue
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsUE library.
|
||||
*
|
||||
* srsUE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsUE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* File: rlc_tx_queue.h
|
||||
* Description: Queue used in RLC TM/UM/AM TX queues.
|
||||
* Uses a blocking queue with bounded capacity to block higher layers
|
||||
* when pushing Uplink traffic
|
||||
* Reference:
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef SRSLTE_MSG_QUEUE_H
|
||||
#define SRSLTE_MSG_QUEUE_H
|
||||
|
||||
#include "srslte/common/block_queue.h"
|
||||
#include "srslte/common/common.h"
|
||||
#include <pthread.h>
|
||||
|
||||
namespace srslte {
|
||||
|
||||
class rlc_tx_queue : public block_queue<byte_buffer_t*>::call_mutexed_itf
|
||||
{
|
||||
public:
|
||||
rlc_tx_queue(uint32_t capacity = 128) : queue((int) capacity) {
|
||||
unread_bytes = 0;
|
||||
queue.set_mutexed_itf(this);
|
||||
}
|
||||
// increase/decrease unread_bytes inside push/pop mutexed operations
|
||||
void pushing(byte_buffer_t *msg) {
|
||||
unread_bytes += msg->N_bytes;
|
||||
}
|
||||
void popping(byte_buffer_t *msg) {
|
||||
if (unread_bytes > msg->N_bytes) {
|
||||
unread_bytes -= msg->N_bytes;
|
||||
} else {
|
||||
unread_bytes = 0;
|
||||
}
|
||||
}
|
||||
void write(byte_buffer_t *msg)
|
||||
{
|
||||
queue.push(msg);
|
||||
}
|
||||
|
||||
void read(byte_buffer_t **msg)
|
||||
{
|
||||
byte_buffer_t *m = queue.wait_pop();
|
||||
*msg = m;
|
||||
}
|
||||
|
||||
bool try_read(byte_buffer_t **msg)
|
||||
{
|
||||
return queue.try_pop(msg);
|
||||
}
|
||||
|
||||
void resize(uint32_t capacity)
|
||||
{
|
||||
queue.resize(capacity);
|
||||
}
|
||||
uint32_t size()
|
||||
{
|
||||
return (uint32_t) queue.size();
|
||||
}
|
||||
|
||||
uint32_t size_bytes()
|
||||
{
|
||||
return unread_bytes;
|
||||
}
|
||||
|
||||
uint32_t size_tail_bytes()
|
||||
{
|
||||
if (!queue.empty()) {
|
||||
byte_buffer_t *m = queue.front();
|
||||
if (m) {
|
||||
return m->N_bytes;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This is a hack to reset N_bytes counter when queue is corrupted (see line 89)
|
||||
void reset() {
|
||||
unread_bytes = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_empty() { return queue.empty(); }
|
||||
|
||||
block_queue<byte_buffer_t*> queue;
|
||||
uint32_t unread_bytes;
|
||||
};
|
||||
|
||||
} // namespace srslte
|
||||
|
||||
|
||||
#endif // SRSLTE_MSG_QUEUE_H
|
|
@ -31,7 +31,7 @@
|
|||
#include "srslte/common/log.h"
|
||||
#include "srslte/common/common.h"
|
||||
#include "srslte/interfaces/ue_interfaces.h"
|
||||
#include "srslte/common/msg_queue.h"
|
||||
#include "srslte/upper/rlc_tx_queue.h"
|
||||
#include "srslte/upper/rlc_common.h"
|
||||
#include <pthread.h>
|
||||
#include <map>
|
||||
|
@ -50,17 +50,18 @@ class rlc_um
|
|||
{
|
||||
public:
|
||||
rlc_um();
|
||||
~rlc_um();
|
||||
|
||||
void init(log *rlc_entity_log_,
|
||||
uint32_t lcid_,
|
||||
srsue::pdcp_interface_rlc *pdcp_,
|
||||
srsue::rrc_interface_rlc *rrc_,
|
||||
mac_interface_timers *mac_timers_);
|
||||
~rlc_um();
|
||||
void init(log *rlc_entity_log_,
|
||||
uint32_t lcid_,
|
||||
srsue::pdcp_interface_rlc *pdcp_,
|
||||
srsue::rrc_interface_rlc *rrc_,
|
||||
mac_interface_timers *mac_timers_);
|
||||
void configure(srslte_rlc_config_t cnfg);
|
||||
void reset();
|
||||
void stop();
|
||||
void empty_queue();
|
||||
bool is_mrb();
|
||||
|
||||
rlc_mode_t get_mode();
|
||||
uint32_t get_bearer();
|
||||
|
@ -73,7 +74,7 @@ public:
|
|||
uint32_t get_total_buffer_state();
|
||||
int read_pdu(uint8_t *payload, uint32_t nof_bytes);
|
||||
void write_pdu(uint8_t *payload, uint32_t nof_bytes);
|
||||
|
||||
int get_increment_sequence_num();
|
||||
// Timeout callback interface
|
||||
void timer_expired(uint32_t timeout_id);
|
||||
|
||||
|
@ -86,11 +87,12 @@ private:
|
|||
uint32_t lcid;
|
||||
srsue::pdcp_interface_rlc *pdcp;
|
||||
srsue::rrc_interface_rlc *rrc;
|
||||
mac_interface_timers *mac_timers;
|
||||
mac_interface_timers *mac_timers;
|
||||
|
||||
// TX SDU buffers
|
||||
msg_queue tx_sdu_queue;
|
||||
rlc_tx_queue tx_sdu_queue;
|
||||
byte_buffer_t *tx_sdu;
|
||||
byte_buffer_t tx_sdu_temp;
|
||||
|
||||
// Rx window
|
||||
std::map<uint32_t, rlc_umd_pdu_t> rx_window;
|
||||
|
@ -136,6 +138,8 @@ private:
|
|||
void reassemble_rx_sdus();
|
||||
bool inside_reordering_window(uint16_t sn);
|
||||
void debug_state();
|
||||
|
||||
std::string rb_name();
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -1027,6 +1027,7 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_authentication_parameter_rand_ie(uint8 **ie_
|
|||
Document Reference: 24.301 v10.2.0 Section 9.9.3.4
|
||||
*********************************************************************/
|
||||
LIBLTE_ERROR_ENUM liblte_mme_pack_authentication_response_parameter_ie(uint8 *res,
|
||||
int res_len,
|
||||
uint8 **ie_ptr)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
|
@ -1035,12 +1036,13 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_authentication_response_parameter_ie(uint8 *r
|
|||
if(res != NULL &&
|
||||
ie_ptr != NULL)
|
||||
{
|
||||
(*ie_ptr)[0] = 8;
|
||||
for(i=0; i<8; i++)
|
||||
(*ie_ptr)[0] = res_len;
|
||||
*ie_ptr += 1;
|
||||
for(i=0; i<res_len; i++)
|
||||
{
|
||||
(*ie_ptr)[i+1] = res[i];
|
||||
(*ie_ptr)[i] = res[i];
|
||||
}
|
||||
*ie_ptr += 9;
|
||||
*ie_ptr += res_len;
|
||||
|
||||
err = LIBLTE_SUCCESS;
|
||||
}
|
||||
|
@ -2225,14 +2227,14 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_network_name_ie(LIBLTE_MME_NETWORK_NAME_STRUCT
|
|||
uint32 i;
|
||||
uint32 bit_offset;
|
||||
uint32 byte_offset;
|
||||
const char *char_str = net_name->name.c_str();
|
||||
const char *char_str = net_name->name;
|
||||
|
||||
if(net_name != NULL &&
|
||||
ie_ptr != NULL)
|
||||
{
|
||||
bit_offset = 0;
|
||||
byte_offset = 2;
|
||||
for(i=0; i<net_name->name.size(); i++)
|
||||
for(i=0; i<strnlen(char_str, LIBLTE_STRING_LEN); i++)
|
||||
{
|
||||
if(char_str[i] == 0x0A ||
|
||||
char_str[i] == 0x0D ||
|
||||
|
@ -2319,6 +2321,7 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_network_name_ie(uint8
|
|||
uint32 N_bytes;
|
||||
uint8 spare_field;
|
||||
char tmp_char;
|
||||
uint32 str_cnt;
|
||||
|
||||
if(ie_ptr != NULL &&
|
||||
net_name != NULL)
|
||||
|
@ -2328,8 +2331,9 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_network_name_ie(uint8
|
|||
N_bytes = (*ie_ptr)[0];
|
||||
bit_offset = 0;
|
||||
byte_offset = 2;
|
||||
net_name->name = "";
|
||||
while(byte_offset < N_bytes)
|
||||
str_cnt = 0;
|
||||
|
||||
while(byte_offset < N_bytes && str_cnt < LIBLTE_STRING_LEN)
|
||||
{
|
||||
switch(bit_offset)
|
||||
{
|
||||
|
@ -2389,7 +2393,10 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_network_name_ie(uint8
|
|||
(tmp_char >= 0x61 &&
|
||||
tmp_char <= 0x7A))
|
||||
{
|
||||
net_name->name += tmp_char;
|
||||
if (str_cnt < LIBLTE_STRING_LEN) {
|
||||
net_name->name[str_cnt] = tmp_char;
|
||||
str_cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2412,10 +2419,18 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_network_name_ie(uint8
|
|||
(tmp_char >= 0x61 &&
|
||||
tmp_char <= 0x7A))
|
||||
{
|
||||
net_name->name += tmp_char;
|
||||
if (str_cnt < LIBLTE_STRING_LEN) {
|
||||
net_name->name[str_cnt] = tmp_char;
|
||||
str_cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (str_cnt < LIBLTE_STRING_LEN) {
|
||||
net_name->name[str_cnt] = '\0';
|
||||
str_cnt++;
|
||||
}
|
||||
|
||||
*ie_ptr += byte_offset + 1;
|
||||
|
||||
err = LIBLTE_SUCCESS;
|
||||
|
@ -3765,12 +3780,12 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_access_point_name_ie(LIBLTE_MME_ACCESS_POINT_N
|
|||
if(apn != NULL &&
|
||||
ie_ptr != NULL)
|
||||
{
|
||||
apn_str = apn->apn.c_str();
|
||||
(*ie_ptr)[0] = apn->apn.length()+1;
|
||||
apn_str = apn->apn;
|
||||
(*ie_ptr)[0] = strnlen(apn->apn, LIBLTE_STRING_LEN)+1;
|
||||
len_idx = 0;
|
||||
apn_idx = 0;
|
||||
label_len = 0;
|
||||
while(apn->apn.length() > apn_idx)
|
||||
while(strnlen(apn->apn, LIBLTE_STRING_LEN) > apn_idx)
|
||||
{
|
||||
(*ie_ptr)[1+apn_idx+1] = (uint8)apn_str[apn_idx];
|
||||
apn_idx++;
|
||||
|
@ -3785,7 +3800,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_access_point_name_ie(LIBLTE_MME_ACCESS_POINT_N
|
|||
}
|
||||
}
|
||||
(*ie_ptr)[1+len_idx] = label_len;
|
||||
*ie_ptr += apn->apn.length() + 2;
|
||||
*ie_ptr += strnlen(apn->apn, LIBLTE_STRING_LEN) + 2;
|
||||
|
||||
err = LIBLTE_SUCCESS;
|
||||
}
|
||||
|
@ -3799,26 +3814,31 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_access_point_name_ie(uint8
|
|||
uint32 i;
|
||||
uint32 ie_idx;
|
||||
uint32 label_len;
|
||||
uint32 str_cnt;
|
||||
|
||||
if(ie_ptr != NULL &&
|
||||
apn != NULL)
|
||||
{
|
||||
apn->apn.clear();
|
||||
ie_idx = 0;
|
||||
while(ie_idx < (*ie_ptr)[0])
|
||||
str_cnt = 0;
|
||||
while(ie_idx < (*ie_ptr)[0] && str_cnt < LIBLTE_STRING_LEN)
|
||||
{
|
||||
label_len = (*ie_ptr)[1+ie_idx];
|
||||
for(i=0; i<label_len; i++)
|
||||
for(i=0; i<label_len && str_cnt < LIBLTE_STRING_LEN; i++)
|
||||
{
|
||||
apn->apn += (char)((*ie_ptr)[1+ie_idx+i+1]);
|
||||
apn->apn[str_cnt] = (char)((*ie_ptr)[1+ie_idx+i+1]);
|
||||
str_cnt++;
|
||||
}
|
||||
ie_idx += label_len + 1;
|
||||
if(ie_idx < (*ie_ptr)[0])
|
||||
if(ie_idx < (*ie_ptr)[0] && str_cnt < LIBLTE_STRING_LEN)
|
||||
{
|
||||
apn->apn += '.';
|
||||
apn->apn[str_cnt] = '.';
|
||||
str_cnt++;
|
||||
}
|
||||
}
|
||||
apn->apn += "\0";
|
||||
if (str_cnt < LIBLTE_STRING_LEN) {
|
||||
apn->apn[str_cnt] = '\0';
|
||||
}
|
||||
*ie_ptr += (*ie_ptr)[0] + 1;
|
||||
|
||||
err = LIBLTE_SUCCESS;
|
||||
|
@ -4398,7 +4418,7 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_pdn_address_ie(uint8
|
|||
pdn_addr->addr[i] = (*ie_ptr)[2+i];
|
||||
}
|
||||
}
|
||||
*ie_ptr += (*ie_ptr)[0];
|
||||
*ie_ptr += (*ie_ptr)[0] + 1;
|
||||
|
||||
err = LIBLTE_SUCCESS;
|
||||
}
|
||||
|
@ -6177,7 +6197,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_authentication_response_msg(LIBLTE_MME_AUTHENT
|
|||
msg_ptr++;
|
||||
|
||||
// Authentication Response Parameter (RES)
|
||||
liblte_mme_pack_authentication_response_parameter_ie(auth_resp->res, &msg_ptr);
|
||||
liblte_mme_pack_authentication_response_parameter_ie(auth_resp->res, auth_resp->res_len, &msg_ptr);
|
||||
|
||||
// Fill in the number of bytes used
|
||||
msg->N_bytes = msg_ptr - msg->msg;
|
||||
|
@ -9943,7 +9963,7 @@ LIBLTE_ERROR_ENUM srslte_mme_pack_esm_information_request_msg(LIBLTE_MME_ESM_INF
|
|||
if(LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS != sec_hdr_type)
|
||||
{
|
||||
// Protocol Discriminator and Security Header Type
|
||||
*msg_ptr = (sec_hdr_type << 4) | (LIBLTE_MME_PD_EPS_SESSION_MANAGEMENT);
|
||||
*msg_ptr = (sec_hdr_type << 4) | (LIBLTE_MME_PD_EPS_MOBILITY_MANAGEMENT);
|
||||
msg_ptr++;
|
||||
|
||||
// MAC will be filled in later
|
||||
|
@ -10022,10 +10042,19 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_esm_information_request_msg(LIBLTE_BYTE_MSG_
|
|||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
uint8 *msg_ptr = msg->msg;
|
||||
uint8 sec_hdr_type;
|
||||
|
||||
if(msg != NULL &&
|
||||
esm_info_req != NULL)
|
||||
{
|
||||
// Security Header Type
|
||||
sec_hdr_type = (msg->msg[0] & 0xF0) >> 4;
|
||||
if(LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS == sec_hdr_type) {
|
||||
msg_ptr++;
|
||||
} else{
|
||||
msg_ptr += 6;
|
||||
}
|
||||
|
||||
// EPS Bearer ID
|
||||
esm_info_req->eps_bearer_id = (*msg_ptr >> 4);
|
||||
msg_ptr++;
|
||||
|
@ -10053,6 +10082,8 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_esm_information_request_msg(LIBLTE_BYTE_MSG_
|
|||
Document Reference: 24.301 v10.2.0 Section 8.3.14
|
||||
*********************************************************************/
|
||||
LIBLTE_ERROR_ENUM liblte_mme_pack_esm_information_response_msg(LIBLTE_MME_ESM_INFORMATION_RESPONSE_MSG_STRUCT *esm_info_resp,
|
||||
uint8 sec_hdr_type,
|
||||
uint32 count,
|
||||
LIBLTE_BYTE_MSG_STRUCT *msg)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
|
@ -10061,6 +10092,20 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_esm_information_response_msg(LIBLTE_MME_ESM_IN
|
|||
if(esm_info_resp != NULL &&
|
||||
msg != NULL)
|
||||
{
|
||||
if(LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS != sec_hdr_type)
|
||||
{
|
||||
// Protocol Discriminator and Security Header Type
|
||||
*msg_ptr = (sec_hdr_type << 4) | (LIBLTE_MME_PD_EPS_MOBILITY_MANAGEMENT);
|
||||
msg_ptr++;
|
||||
|
||||
// MAC will be filled in later
|
||||
msg_ptr += 4;
|
||||
|
||||
// Sequence Number
|
||||
*msg_ptr = count & 0xFF;
|
||||
msg_ptr++;
|
||||
}
|
||||
|
||||
// Protocol Discriminator and EPS Bearer ID
|
||||
*msg_ptr = (esm_info_resp->eps_bearer_id << 4) | (LIBLTE_MME_PD_EPS_SESSION_MANAGEMENT);
|
||||
msg_ptr++;
|
||||
|
@ -10097,6 +10142,8 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_esm_information_response_msg(LIBLTE_MME_ESM_IN
|
|||
|
||||
return(err);
|
||||
}
|
||||
|
||||
|
||||
LIBLTE_ERROR_ENUM srslte_mme_unpack_esm_information_response_msg(LIBLTE_BYTE_MSG_STRUCT *msg,
|
||||
LIBLTE_MME_ESM_INFORMATION_RESPONSE_MSG_STRUCT *esm_info_resp)
|
||||
{
|
||||
|
@ -10114,7 +10161,7 @@ LIBLTE_ERROR_ENUM srslte_mme_unpack_esm_information_response_msg(LIBLTE_BYTE_MSG
|
|||
{
|
||||
msg_ptr++;
|
||||
}else{
|
||||
msg_ptr += 7;
|
||||
msg_ptr += 6;
|
||||
}
|
||||
// EPS Bearer ID
|
||||
esm_info_resp->eps_bearer_id = (*msg_ptr >> 4);
|
||||
|
|
|
@ -327,13 +327,218 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_mbsfn_subframe_config_ie(uint8
|
|||
}
|
||||
|
||||
/*********************************************************************
|
||||
IE Name: PMCH Info List
|
||||
IE Name: TMGI
|
||||
|
||||
Description: Specifies configuration of all PMCHs of an MBSFN area
|
||||
Description: Temporary Mobile Group Identity (PLMN + MBMS service ID)
|
||||
|
||||
Document Reference: 36.331 v10.0.0 Section 6.3.7
|
||||
*********************************************************************/
|
||||
// FIXME
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_pack_tmgi_r9_ie(LIBLTE_RRC_TMGI_R9_STRUCT *tmgi,
|
||||
uint8 **ie_ptr)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if(tmgi != NULL &&
|
||||
ie_ptr != NULL)
|
||||
{
|
||||
liblte_value_2_bits(tmgi->plmn_id_explicit?1:0, ie_ptr, 1);
|
||||
if(tmgi->plmn_id_explicit){
|
||||
liblte_rrc_pack_plmn_identity_ie(&tmgi->plmn_id_r9, ie_ptr);
|
||||
}else{
|
||||
liblte_value_2_bits(tmgi->plmn_index_r9-1, ie_ptr, 3);
|
||||
}
|
||||
liblte_value_2_bits(tmgi->serviceid_r9, ie_ptr, 24);
|
||||
|
||||
err = LIBLTE_SUCCESS;
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_unpack_tmgi_r9_ie(uint8 **ie_ptr,
|
||||
LIBLTE_RRC_TMGI_R9_STRUCT *tmgi)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if(ie_ptr != NULL &&
|
||||
tmgi != NULL)
|
||||
{
|
||||
tmgi->plmn_id_explicit = liblte_bits_2_value(ie_ptr, 1);
|
||||
if(tmgi->plmn_id_explicit){
|
||||
liblte_rrc_unpack_plmn_identity_ie(ie_ptr, &tmgi->plmn_id_r9);
|
||||
}else{
|
||||
tmgi->plmn_index_r9 = liblte_bits_2_value(ie_ptr, 3) + 1;
|
||||
}
|
||||
tmgi->serviceid_r9 = liblte_bits_2_value(ie_ptr, 24);
|
||||
|
||||
err = LIBLTE_SUCCESS;
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
IE Name: MBMS Session Info
|
||||
|
||||
Description: Information about an individual MBMS session
|
||||
|
||||
Document Reference: 36.331 v10.0.0 Section 6.3.7
|
||||
*********************************************************************/
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_pack_mbms_session_info_r9_ie(LIBLTE_RRC_MBMS_SESSION_INFO_R9_STRUCT *mbms_session_info,
|
||||
uint8 **ie_ptr)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if(mbms_session_info != NULL &&
|
||||
ie_ptr != NULL)
|
||||
{
|
||||
// ext
|
||||
liblte_value_2_bits(0, ie_ptr, 1);
|
||||
|
||||
liblte_value_2_bits(mbms_session_info->sessionid_r9_present?1:0, ie_ptr, 1);
|
||||
liblte_rrc_pack_tmgi_r9_ie(&mbms_session_info->tmgi_r9, ie_ptr);
|
||||
if(mbms_session_info->sessionid_r9_present){
|
||||
liblte_value_2_bits(mbms_session_info->sessionid_r9, ie_ptr, 8);
|
||||
}
|
||||
liblte_value_2_bits(mbms_session_info->logicalchannelid_r9, ie_ptr, 5);
|
||||
|
||||
err = LIBLTE_SUCCESS;
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_unpack_mbms_session_info_r9_ie(uint8 **ie_ptr,
|
||||
LIBLTE_RRC_MBMS_SESSION_INFO_R9_STRUCT *mbms_session_info)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if(ie_ptr != NULL &&
|
||||
mbms_session_info != NULL)
|
||||
{
|
||||
// ext
|
||||
bool ext = liblte_bits_2_value(ie_ptr, 1);
|
||||
|
||||
mbms_session_info->sessionid_r9_present = liblte_bits_2_value(ie_ptr, 1);
|
||||
liblte_rrc_unpack_tmgi_r9_ie(ie_ptr, &mbms_session_info->tmgi_r9);
|
||||
if(mbms_session_info->sessionid_r9_present){
|
||||
mbms_session_info->sessionid_r9 = liblte_bits_2_value(ie_ptr, 8);
|
||||
}
|
||||
mbms_session_info->logicalchannelid_r9 = liblte_bits_2_value(ie_ptr, 5);
|
||||
|
||||
liblte_rrc_consume_noncrit_extension(ext, __func__, ie_ptr);
|
||||
|
||||
err = LIBLTE_SUCCESS;
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
IE Name: PMCH Config
|
||||
|
||||
Description: Contains configuration parameters of the sessions
|
||||
carried by a PMCH
|
||||
|
||||
Document Reference: 36.331 v10.0.0 Section 6.3.7
|
||||
*********************************************************************/
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_pack_pmch_config_r9_ie(LIBLTE_RRC_PMCH_CONFIG_R9_STRUCT *pmch_cnfg,
|
||||
uint8 **ie_ptr)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if(pmch_cnfg != NULL &&
|
||||
ie_ptr != NULL)
|
||||
{
|
||||
// ext
|
||||
liblte_value_2_bits(0, ie_ptr, 1);
|
||||
|
||||
liblte_value_2_bits(pmch_cnfg->sf_alloc_end_r9, ie_ptr, 11);
|
||||
liblte_value_2_bits(pmch_cnfg->datamcs_r9, ie_ptr, 5);
|
||||
liblte_value_2_bits(pmch_cnfg->mch_schedulingperiod_r9, ie_ptr, 3);
|
||||
|
||||
err = LIBLTE_SUCCESS;
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_unpack_pmch_config_r9_ie(uint8 **ie_ptr,
|
||||
LIBLTE_RRC_PMCH_CONFIG_R9_STRUCT *pmch_cnfg)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if(ie_ptr != NULL &&
|
||||
pmch_cnfg != NULL)
|
||||
{
|
||||
// ext
|
||||
bool ext = liblte_bits_2_value(ie_ptr, 1);
|
||||
|
||||
pmch_cnfg->sf_alloc_end_r9 = liblte_bits_2_value(ie_ptr, 11);
|
||||
pmch_cnfg->datamcs_r9 = liblte_bits_2_value(ie_ptr, 5);
|
||||
pmch_cnfg->mch_schedulingperiod_r9 = (LIBLTE_RRC_MCH_SCHEDULING_PERIOD_R9_ENUM)liblte_bits_2_value(ie_ptr, 3);
|
||||
|
||||
liblte_rrc_consume_noncrit_extension(ext, __func__, ie_ptr);
|
||||
|
||||
err = LIBLTE_SUCCESS;
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
IE Name: PMCH Info
|
||||
|
||||
Description: Specifies configuration of PMCH of an MBSFN area
|
||||
|
||||
Document Reference: 36.331 v10.0.0 Section 6.3.7
|
||||
*********************************************************************/
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_pack_pmch_info_r9_ie(LIBLTE_RRC_PMCH_INFO_R9_STRUCT *pmch_info,
|
||||
uint8 **ie_ptr)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
uint32 i;
|
||||
|
||||
if(pmch_info != NULL &&
|
||||
ie_ptr != NULL)
|
||||
{
|
||||
// ext
|
||||
liblte_value_2_bits(0, ie_ptr, 1);
|
||||
|
||||
liblte_rrc_pack_pmch_config_r9_ie(&pmch_info->pmch_config_r9, ie_ptr);
|
||||
liblte_value_2_bits(pmch_info->mbms_sessioninfolist_r9_size, ie_ptr, 5);
|
||||
for(i=0; i<pmch_info->mbms_sessioninfolist_r9_size; i++){
|
||||
liblte_rrc_pack_mbms_session_info_r9_ie(&pmch_info->mbms_sessioninfolist_r9[i], ie_ptr);
|
||||
}
|
||||
|
||||
err = LIBLTE_SUCCESS;
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_unpack_pmch_info_r9_ie(uint8 **ie_ptr,
|
||||
LIBLTE_RRC_PMCH_INFO_R9_STRUCT *pmch_info)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
uint32 i;
|
||||
|
||||
if(ie_ptr != NULL &&
|
||||
pmch_info != NULL)
|
||||
{
|
||||
// ext
|
||||
bool ext = liblte_bits_2_value(ie_ptr, 1);
|
||||
|
||||
liblte_rrc_unpack_pmch_config_r9_ie(ie_ptr, &pmch_info->pmch_config_r9);
|
||||
pmch_info->mbms_sessioninfolist_r9_size = liblte_bits_2_value(ie_ptr, 5);
|
||||
for(i=0; i<pmch_info->mbms_sessioninfolist_r9_size; i++){
|
||||
liblte_rrc_unpack_mbms_session_info_r9_ie(ie_ptr, &pmch_info->mbms_sessioninfolist_r9[i]);
|
||||
}
|
||||
|
||||
liblte_rrc_consume_noncrit_extension(ext, __func__, ie_ptr);
|
||||
|
||||
err = LIBLTE_SUCCESS;
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
IE Name: C-RNTI
|
||||
|
@ -380,7 +585,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_c_rnti_ie(uint8 **ie_ptr,
|
|||
|
||||
Document Reference: 36.331 v10.0.0 Section 6.3.6
|
||||
*********************************************************************/
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_pack_dedicated_info_cdma2000_ie(LIBLTE_SIMPLE_BYTE_MSG_STRUCT *ded_info_cdma2000,
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_pack_dedicated_info_cdma2000_ie(LIBLTE_BYTE_MSG_STRUCT *ded_info_cdma2000,
|
||||
uint8 **ie_ptr)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
|
@ -412,7 +617,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_dedicated_info_cdma2000_ie(LIBLTE_SIMPLE_BYTE_
|
|||
return(err);
|
||||
}
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_unpack_dedicated_info_cdma2000_ie(uint8 **ie_ptr,
|
||||
LIBLTE_SIMPLE_BYTE_MSG_STRUCT *ded_info_cdma2000)
|
||||
LIBLTE_BYTE_MSG_STRUCT *ded_info_cdma2000)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
uint32 i;
|
||||
|
@ -452,7 +657,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_dedicated_info_cdma2000_ie(uint8
|
|||
|
||||
Document Reference: 36.331 v10.0.0 Section 6.3.6
|
||||
*********************************************************************/
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_pack_dedicated_info_nas_ie(LIBLTE_SIMPLE_BYTE_MSG_STRUCT *ded_info_nas,
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_pack_dedicated_info_nas_ie(LIBLTE_BYTE_MSG_STRUCT *ded_info_nas,
|
||||
uint8 **ie_ptr)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
|
@ -484,7 +689,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_dedicated_info_nas_ie(LIBLTE_SIMPLE_BYTE_MSG_S
|
|||
return(err);
|
||||
}
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_unpack_dedicated_info_nas_ie(uint8 **ie_ptr,
|
||||
LIBLTE_SIMPLE_BYTE_MSG_STRUCT *ded_info_nas)
|
||||
LIBLTE_BYTE_MSG_STRUCT *ded_info_nas)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
uint32 i;
|
||||
|
@ -2715,8 +2920,10 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_report_config_eutra_ie(LIBLTE_RRC_REPORT_CONFI
|
|||
liblte_value_2_bits(rep_cnfg_eutra->trigger_type, ie_ptr, 1);
|
||||
if(LIBLTE_RRC_TRIGGER_TYPE_EUTRA_EVENT == rep_cnfg_eutra->trigger_type)
|
||||
{
|
||||
// Event ID choice extension indicator
|
||||
liblte_value_2_bits(0, ie_ptr, 1); // Choice with extension - unlikely to be >63 choices
|
||||
|
||||
// Event ID
|
||||
// FIXME: Handle extension properly
|
||||
liblte_value_2_bits(rep_cnfg_eutra->event.event_id, ie_ptr, 3);
|
||||
if(LIBLTE_RRC_EVENT_ID_EUTRA_A1 == rep_cnfg_eutra->event.event_id)
|
||||
{
|
||||
|
@ -8894,7 +9101,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_sys_info_block_type_2_ie(LIBLTE_RRC_SYS_INFO_B
|
|||
liblte_value_2_bits(sib2->mbsfn_subfr_cnfg_list_size - 1, ie_ptr, 3);
|
||||
for(i=0; i<sib2->mbsfn_subfr_cnfg_list_size; i++)
|
||||
{
|
||||
liblte_rrc_pack_mbsfn_subframe_config_ie(&sib2->mbsfn_subfr_cnfg[i], ie_ptr);
|
||||
liblte_rrc_pack_mbsfn_subframe_config_ie(&sib2->mbsfn_subfr_cnfg_list[i], ie_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8992,7 +9199,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_sys_info_block_type_2_ie(uint8
|
|||
sib2->mbsfn_subfr_cnfg_list_size = liblte_bits_2_value(ie_ptr, 3) + 1;
|
||||
for(i=0; i<sib2->mbsfn_subfr_cnfg_list_size; i++)
|
||||
{
|
||||
liblte_rrc_unpack_mbsfn_subframe_config_ie(ie_ptr, &sib2->mbsfn_subfr_cnfg[i]);
|
||||
liblte_rrc_unpack_mbsfn_subframe_config_ie(ie_ptr, &sib2->mbsfn_subfr_cnfg_list[i]);
|
||||
}
|
||||
}else{
|
||||
sib2->mbsfn_subfr_cnfg_list_size = 0;
|
||||
|
@ -10286,7 +10493,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_sys_info_block_type_13_ie(LIBLTE_RRC_SYS_INFO_
|
|||
{
|
||||
liblte_rrc_pack_mbsfn_area_info_ie(&sib13->mbsfn_area_info_list_r9[i], ie_ptr);
|
||||
}
|
||||
liblte_rrc_pack_mbsfn_notification_config_ie(&sib13->mbms_notification_config, ie_ptr);
|
||||
liblte_rrc_pack_mbsfn_notification_config_ie(&sib13->mbsfn_notification_config, ie_ptr);
|
||||
|
||||
err = LIBLTE_SUCCESS;
|
||||
}
|
||||
|
@ -10315,7 +10522,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_sys_info_block_type_13_ie(uint8
|
|||
{
|
||||
liblte_rrc_unpack_mbsfn_area_info_ie(ie_ptr, &sib13->mbsfn_area_info_list_r9[i]);
|
||||
}
|
||||
liblte_rrc_unpack_mbsfn_notification_config_ie(ie_ptr, &sib13->mbms_notification_config);
|
||||
liblte_rrc_unpack_mbsfn_notification_config_ie(ie_ptr, &sib13->mbsfn_notification_config);
|
||||
|
||||
liblte_rrc_consume_noncrit_extension(ext_ind, __func__, ie_ptr);
|
||||
|
||||
|
@ -12999,9 +13206,82 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_measurement_report_msg(LIBLTE_BIT_MSG_STRUCT
|
|||
Description: Contains the MBMS control information applicable for
|
||||
an MBSFN area
|
||||
|
||||
Document Reference: 36.331 v10.0.0 Section 6.2.2
|
||||
Document Reference: 36.331 v10.0.0 Section 6.2.2
|
||||
*********************************************************************/
|
||||
// FIXME
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_pack_mbsfn_area_configuration_r9_msg(LIBLTE_RRC_MBSFN_AREA_CONFIGURATION_R9_STRUCT *mbsfn_area_cnfg,
|
||||
LIBLTE_BIT_MSG_STRUCT *msg)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
uint8 *msg_ptr = msg->msg;
|
||||
uint32 i;
|
||||
|
||||
if(mbsfn_area_cnfg != NULL &&
|
||||
msg != NULL)
|
||||
{
|
||||
// Non-critical extension
|
||||
liblte_value_2_bits(0, &msg_ptr, 1);
|
||||
|
||||
// commonsf_allocpatternlist_r9
|
||||
liblte_value_2_bits(mbsfn_area_cnfg->commonsf_allocpatternlist_r9_size-1, &msg_ptr, 3);
|
||||
for(i=0; i<mbsfn_area_cnfg->commonsf_allocpatternlist_r9_size; i++){
|
||||
liblte_rrc_pack_mbsfn_subframe_config_ie(&mbsfn_area_cnfg->commonsf_allocpatternlist_r9[i], &msg_ptr);
|
||||
}
|
||||
|
||||
// commonsf_allocperiod_r9
|
||||
liblte_value_2_bits(mbsfn_area_cnfg->commonsf_allocperiod_r9, &msg_ptr, 3);
|
||||
|
||||
// pmch_infolist_r9
|
||||
liblte_value_2_bits(mbsfn_area_cnfg->pmch_infolist_r9_size, &msg_ptr, 4);
|
||||
for(i=0; i<mbsfn_area_cnfg->pmch_infolist_r9_size; i++){
|
||||
liblte_rrc_pack_pmch_info_r9_ie(&mbsfn_area_cnfg->pmch_infolist_r9[i], &msg_ptr);
|
||||
}
|
||||
|
||||
// Fill in the number of bits used
|
||||
msg->N_bits = msg_ptr - msg->msg;
|
||||
|
||||
err = LIBLTE_SUCCESS;
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_unpack_mbsfn_area_configuration_r9_msg(LIBLTE_BIT_MSG_STRUCT *msg,
|
||||
LIBLTE_RRC_MBSFN_AREA_CONFIGURATION_R9_STRUCT *mbsfn_area_cnfg)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
uint8 *msg_ptr = msg->msg;
|
||||
uint32 i;
|
||||
bool ext;
|
||||
|
||||
if(msg != NULL &&
|
||||
mbsfn_area_cnfg != NULL)
|
||||
{
|
||||
// Non-critical extension
|
||||
ext = liblte_bits_2_value(&msg_ptr, 1);
|
||||
liblte_rrc_warning_not_handled(ext, __func__);
|
||||
|
||||
// commonsf_allocpatternlist_r9
|
||||
mbsfn_area_cnfg->commonsf_allocpatternlist_r9_size = liblte_bits_2_value(&msg_ptr, 3) + 1;
|
||||
for(i=0; i<mbsfn_area_cnfg->commonsf_allocpatternlist_r9_size; i++){
|
||||
liblte_rrc_unpack_mbsfn_subframe_config_ie(&msg_ptr, &mbsfn_area_cnfg->commonsf_allocpatternlist_r9[i]);
|
||||
}
|
||||
|
||||
// commonsf_allocperiod_r9
|
||||
mbsfn_area_cnfg->commonsf_allocperiod_r9 = (LIBLTE_RRC_MBSFN_COMMON_SF_ALLOC_PERIOD_R9_ENUM)liblte_bits_2_value(&msg_ptr, 3);
|
||||
|
||||
// pmch_infolist_r9
|
||||
mbsfn_area_cnfg->pmch_infolist_r9_size = liblte_bits_2_value(&msg_ptr, 4);
|
||||
for(i=0; i<mbsfn_area_cnfg->pmch_infolist_r9_size; i++){
|
||||
liblte_rrc_unpack_pmch_info_r9_ie(&msg_ptr, &mbsfn_area_cnfg->pmch_infolist_r9[i]);
|
||||
}
|
||||
|
||||
liblte_rrc_consume_noncrit_extension(ext, __func__, &msg_ptr);
|
||||
|
||||
err = LIBLTE_SUCCESS;
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
Message Name: Master Information Block
|
||||
|
@ -13102,7 +13382,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_dl_information_transfer_msg(LIBLTE_BIT_MSG_S
|
|||
liblte_bits_2_value(&msg_ptr, 2);
|
||||
|
||||
// Optional indicator
|
||||
liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);;
|
||||
liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);
|
||||
|
||||
// Dedicated info type choice
|
||||
dl_info_transfer->dedicated_info_type = (LIBLTE_RRC_DL_INFORMATION_TRANSFER_TYPE_ENUM)liblte_bits_2_value(&msg_ptr, 2);
|
||||
|
@ -13371,6 +13651,66 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_bcch_dlsch_msg(LIBLTE_BIT_MSG_STRUCT
|
|||
return(err);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Message Name: MCCH Message
|
||||
|
||||
Description: Contains the set of RRC messages that may be sent
|
||||
from the E-UTRAN to the UE on the MCCH logical
|
||||
channel
|
||||
|
||||
Document Reference: 36.331 v10.0.0 Section 6.2.1
|
||||
*********************************************************************/
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_pack_mcch_msg(LIBLTE_RRC_MCCH_MSG_STRUCT *mcch_msg,
|
||||
LIBLTE_BIT_MSG_STRUCT *msg)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
uint8 *msg_ptr = msg->msg;
|
||||
uint8 ext = false;
|
||||
|
||||
if(mcch_msg != NULL &&
|
||||
msg != NULL)
|
||||
{
|
||||
// MCCH choice
|
||||
liblte_value_2_bits(0, &msg_ptr, 1);
|
||||
|
||||
err = liblte_rrc_pack_mbsfn_area_configuration_r9_msg(mcch_msg,
|
||||
&global_msg);
|
||||
if(global_msg.N_bits <= (LIBLTE_MAX_MSG_SIZE_BITS - 1))
|
||||
{
|
||||
memcpy(msg_ptr, global_msg.msg, global_msg.N_bits);
|
||||
msg->N_bits = global_msg.N_bits + 1;
|
||||
}else{
|
||||
msg->N_bits = 0;
|
||||
err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
LIBLTE_ERROR_ENUM liblte_rrc_unpack_mcch_msg(LIBLTE_BIT_MSG_STRUCT *msg,
|
||||
LIBLTE_RRC_MCCH_MSG_STRUCT *mcch_msg)
|
||||
{
|
||||
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
uint8 *msg_ptr = msg->msg;
|
||||
uint32 N_bits_used;
|
||||
|
||||
if(msg != NULL &&
|
||||
mcch_msg != NULL)
|
||||
{
|
||||
// MCCH choice
|
||||
liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);;
|
||||
|
||||
if((msg->N_bits-(msg_ptr-msg->msg)) <= (LIBLTE_MAX_MSG_SIZE_BITS - 1))
|
||||
{
|
||||
memcpy(global_msg.msg, msg_ptr, msg->N_bits-(msg_ptr-msg->msg));
|
||||
err = liblte_rrc_unpack_mbsfn_area_configuration_r9_msg(&global_msg,
|
||||
mcch_msg);
|
||||
}
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Message Name: PCCH Message
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsUE library.
|
||||
*
|
||||
* srsUE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsUE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "srslte/common/gen_mch_tables.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Key Generation
|
||||
*****************************************************************************/
|
||||
|
||||
void generate_frame_table(uint8_t *table, uint8_t alloc)
|
||||
{
|
||||
table[1] = (alloc >> 5) & 0x01;
|
||||
table[2] = (alloc >> 4) & 0x01;
|
||||
table[3] = (alloc >> 3) & 0x01;
|
||||
table[6] = (alloc >> 2) & 0x01;
|
||||
table[7] = (alloc >> 1) & 0x01;
|
||||
table[8] = (alloc >> 0) & 0x01;
|
||||
}
|
||||
|
||||
void generate_mch_table(uint8_t *table, uint32_t sf_alloc, uint8_t num_frames)
|
||||
{
|
||||
if(num_frames == 1){
|
||||
uint8_t alloc = (sf_alloc) & 0x3F;
|
||||
generate_frame_table(table, alloc);
|
||||
} else if(num_frames == 4){
|
||||
for(uint32_t j=0; j<4; j++){
|
||||
uint8_t alloc = (sf_alloc >> 6*(3-j)) & 0x3F;
|
||||
generate_frame_table(&table[j*10], alloc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void generate_mcch_table(uint8_t *table, uint32_t sf_alloc)
|
||||
{
|
||||
uint8_t alloc = (sf_alloc) & 0x3F;
|
||||
generate_frame_table(table, alloc);
|
||||
}
|
|
@ -136,7 +136,7 @@ void log_filter::all_log(srslte::LOG_LEVEL_ENUM level,
|
|||
}
|
||||
|
||||
void log_filter::console(const char * message, ...) {
|
||||
char *args_msg;
|
||||
char *args_msg = NULL;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message, args) > 0)
|
||||
|
@ -147,7 +147,7 @@ void log_filter::console(const char * message, ...) {
|
|||
|
||||
void log_filter::error(const char * message, ...) {
|
||||
if (level >= LOG_LEVEL_ERROR) {
|
||||
char *args_msg;
|
||||
char *args_msg = NULL;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message, args) > 0)
|
||||
|
@ -158,7 +158,7 @@ void log_filter::error(const char * message, ...) {
|
|||
}
|
||||
void log_filter::warning(const char * message, ...) {
|
||||
if (level >= LOG_LEVEL_WARNING) {
|
||||
char *args_msg;
|
||||
char *args_msg = NULL;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message, args) > 0)
|
||||
|
@ -169,7 +169,7 @@ void log_filter::warning(const char * message, ...) {
|
|||
}
|
||||
void log_filter::info(const char * message, ...) {
|
||||
if (level >= LOG_LEVEL_INFO) {
|
||||
char *args_msg;
|
||||
char *args_msg = NULL;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message, args) > 0)
|
||||
|
@ -180,7 +180,7 @@ void log_filter::info(const char * message, ...) {
|
|||
}
|
||||
void log_filter::debug(const char * message, ...) {
|
||||
if (level >= LOG_LEVEL_DEBUG) {
|
||||
char *args_msg;
|
||||
char *args_msg = NULL;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message, args) > 0)
|
||||
|
@ -192,7 +192,7 @@ void log_filter::debug(const char * message, ...) {
|
|||
|
||||
void log_filter::error_hex(const uint8_t *hex, int size, const char * message, ...) {
|
||||
if (level >= LOG_LEVEL_ERROR) {
|
||||
char *args_msg;
|
||||
char *args_msg = NULL;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message, args) > 0)
|
||||
|
@ -203,7 +203,7 @@ void log_filter::error_hex(const uint8_t *hex, int size, const char * message, .
|
|||
}
|
||||
void log_filter::warning_hex(const uint8_t *hex, int size, const char * message, ...) {
|
||||
if (level >= LOG_LEVEL_WARNING) {
|
||||
char *args_msg;
|
||||
char *args_msg = NULL;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message, args) > 0)
|
||||
|
@ -214,7 +214,7 @@ void log_filter::warning_hex(const uint8_t *hex, int size, const char * message,
|
|||
}
|
||||
void log_filter::info_hex(const uint8_t *hex, int size, const char * message, ...) {
|
||||
if (level >= LOG_LEVEL_INFO) {
|
||||
char *args_msg;
|
||||
char *args_msg = NULL;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message, args) > 0)
|
||||
|
@ -225,7 +225,7 @@ void log_filter::info_hex(const uint8_t *hex, int size, const char * message, ..
|
|||
}
|
||||
void log_filter::debug_hex(const uint8_t *hex, int size, const char * message, ...) {
|
||||
if (level >= LOG_LEVEL_DEBUG) {
|
||||
char *args_msg;
|
||||
char *args_msg = NULL;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message, args) > 0)
|
||||
|
|
|
@ -43,8 +43,8 @@ logger_file::logger_file()
|
|||
|
||||
logger_file::~logger_file() {
|
||||
not_done = false;
|
||||
log(new std::string("Closing log\n"));
|
||||
if(inited) {
|
||||
log(new std::string("Closing log\n"));
|
||||
wait_thread_finish();
|
||||
flush();
|
||||
if (logfile) {
|
||||
|
|
|
@ -94,6 +94,10 @@ void mac_pcap::write_dl_pch(uint8_t* pdu, uint32_t pdu_len_bytes, bool crc_ok, u
|
|||
{
|
||||
pack_and_write(pdu, pdu_len_bytes, 0, crc_ok, tti, SRSLTE_PRNTI, DIRECTION_DOWNLINK, P_RNTI);
|
||||
}
|
||||
void mac_pcap::write_dl_mch(uint8_t* pdu, uint32_t pdu_len_bytes, bool crc_ok, uint32_t tti)
|
||||
{
|
||||
pack_and_write(pdu, pdu_len_bytes, 0, crc_ok, tti, SRSLTE_MRNTI, DIRECTION_DOWNLINK, M_RNTI);
|
||||
}
|
||||
void mac_pcap::write_dl_sirnti(uint8_t* pdu, uint32_t pdu_len_bytes, bool crc_ok, uint32_t tti)
|
||||
{
|
||||
pack_and_write(pdu, pdu_len_bytes, 0, crc_ok, tti, SRSLTE_SIRNTI, DIRECTION_DOWNLINK, SI_RNTI);
|
||||
|
|
|
@ -40,60 +40,15 @@ static uint32_t btable[64] = {
|
|||
|
||||
|
||||
namespace srslte {
|
||||
|
||||
|
||||
|
||||
void sch_pdu::fprint(FILE* stream)
|
||||
{
|
||||
fprintf(stream, "MAC SDU for UL/DL-SCH. ");
|
||||
pdu::fprint(stream);
|
||||
}
|
||||
|
||||
void sch_subh::fprint(FILE* stream)
|
||||
{
|
||||
if (is_sdu()) {
|
||||
fprintf(stream, "SDU LCHID=%d, SDU nof_bytes=%d\n", lcid, nof_bytes);
|
||||
} else {
|
||||
if (parent->is_ul()) {
|
||||
switch(lcid) {
|
||||
case CRNTI:
|
||||
fprintf(stream, "C-RNTI CE\n");
|
||||
break;
|
||||
case PHR_REPORT:
|
||||
fprintf(stream, "PHR\n");
|
||||
break;
|
||||
case TRUNC_BSR:
|
||||
fprintf(stream, "Truncated BSR CE\n");
|
||||
break;
|
||||
case SHORT_BSR:
|
||||
fprintf(stream, "Short BSR CE\n");
|
||||
break;
|
||||
case LONG_BSR:
|
||||
fprintf(stream, "Long BSR CE\n");
|
||||
break;
|
||||
case PADDING:
|
||||
fprintf(stream, "PADDING\n");
|
||||
}
|
||||
} else {
|
||||
switch(lcid) {
|
||||
case CON_RES_ID:
|
||||
fprintf(stream, "Contention Resolution ID CE: 0x%lx\n", get_con_res_id());
|
||||
break;
|
||||
case TA_CMD:
|
||||
fprintf(stream, "Time Advance Command CE: %d\n", get_ta_cmd());
|
||||
break;
|
||||
case DRX_CMD:
|
||||
fprintf(stream, "DRX Command CE: Not implemented\n");
|
||||
break;
|
||||
case PADDING:
|
||||
fprintf(stream, "PADDING\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sch_pdu::parse_packet(uint8_t *ptr)
|
||||
{
|
||||
|
||||
pdu::parse_packet(ptr);
|
||||
|
||||
// Correct size for last SDU
|
||||
|
@ -103,8 +58,10 @@ void sch_pdu::parse_packet(uint8_t *ptr)
|
|||
read_len += subheaders[i].size_plus_header();
|
||||
}
|
||||
|
||||
if (pdu_len-read_len-1 >= 0) {
|
||||
subheaders[nof_subheaders-1].set_payload_size(pdu_len-read_len-1);
|
||||
int n_sub = pdu_len-read_len-1;
|
||||
|
||||
if (n_sub >= 0) {
|
||||
subheaders[nof_subheaders-1].set_payload_size(n_sub);
|
||||
} else {
|
||||
fprintf(stderr,"Reading MAC PDU: negative payload for last subheader\n");
|
||||
}
|
||||
|
@ -155,7 +112,8 @@ uint8_t* sch_pdu::write_packet(srslte::log *log_h)
|
|||
onetwo_padding = rem_len;
|
||||
rem_len = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Determine the header size and CE payload size */
|
||||
uint32_t header_sz = 0;
|
||||
uint32_t ce_payload_sz = 0;
|
||||
|
@ -171,12 +129,12 @@ uint8_t* sch_pdu::write_packet(srslte::log *log_h)
|
|||
header_sz += onetwo_padding;
|
||||
}
|
||||
if (ce_payload_sz + header_sz >= sdu_offset_start) {
|
||||
fprintf(stderr, "Writting PDU: header sz + ce_payload_sz >= sdu_offset_start (%d>=%d). pdu_len=%d, total_sdu_len=%d\n",
|
||||
fprintf(stderr, "Writing PDU: header sz + ce_payload_sz >= sdu_offset_start (%d>=%d). pdu_len=%d, total_sdu_len=%d\n",
|
||||
header_sz + ce_payload_sz, sdu_offset_start, pdu_len, total_sdu_len);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Start writting header and CE payload before the start of the SDU payload */
|
||||
/* Start writing header and CE payload before the start of the SDU payload */
|
||||
uint8_t *ptr = &buffer_tx[sdu_offset_start-header_sz-ce_payload_sz];
|
||||
uint8_t *pdu_start_ptr = ptr;
|
||||
|
||||
|
@ -211,7 +169,6 @@ uint8_t* sch_pdu::write_packet(srslte::log *log_h)
|
|||
subheaders[i].write_payload(&ptr);
|
||||
}
|
||||
}
|
||||
|
||||
// Set padding to zeros (if any)
|
||||
if (rem_len > 0) {
|
||||
bzero(&pdu_start_ptr[pdu_len-rem_len], rem_len*sizeof(uint8_t));
|
||||
|
@ -275,19 +232,22 @@ uint32_t sch_pdu::size_header_sdu(uint32_t nbytes)
|
|||
return 3;
|
||||
}
|
||||
}
|
||||
bool sch_pdu::has_space_ce(uint32_t nbytes)
|
||||
|
||||
bool sch_pdu::has_space_ce(uint32_t nbytes, bool var_len)
|
||||
{
|
||||
if (rem_len >= nbytes + 1) {
|
||||
uint32_t head_len = var_len ? size_header_sdu(nbytes) : 1;
|
||||
if (rem_len >= nbytes + head_len) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool sch_pdu::update_space_ce(uint32_t nbytes)
|
||||
bool sch_pdu::update_space_ce(uint32_t nbytes, bool var_len)
|
||||
{
|
||||
uint32_t head_len = var_len ? size_header_sdu(nbytes) : 1;
|
||||
if (has_space_ce(nbytes)) {
|
||||
rem_len -= nbytes + 1;
|
||||
rem_len -= nbytes + head_len;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -334,18 +294,22 @@ int sch_pdu::get_sdu_space()
|
|||
|
||||
void sch_subh::init()
|
||||
{
|
||||
lcid = 0;
|
||||
nof_bytes = 0;
|
||||
payload = NULL;
|
||||
lcid = 0;
|
||||
nof_bytes = 0;
|
||||
payload = NULL;
|
||||
nof_mch_sched_ce = 0;
|
||||
cur_mch_sched_ce = 0;
|
||||
}
|
||||
|
||||
sch_subh::cetype sch_subh::ce_type()
|
||||
{
|
||||
if (lcid >= PHR_REPORT) {
|
||||
return (cetype) lcid;
|
||||
} else {
|
||||
return SDU;
|
||||
if (lcid >= PHR_REPORT && type == SCH_SUBH_TYPE) {
|
||||
return (cetype)lcid;
|
||||
}
|
||||
if(lcid >= MCH_SCHED_INFO && type == MCH_SUBH_TYPE) {
|
||||
return (cetype)lcid;
|
||||
}
|
||||
return (cetype)SDU;
|
||||
}
|
||||
|
||||
void sch_subh::set_payload_size(uint32_t size) {
|
||||
|
@ -353,48 +317,65 @@ void sch_subh::set_payload_size(uint32_t size) {
|
|||
}
|
||||
|
||||
uint32_t sch_subh::size_plus_header() {
|
||||
if (is_sdu()) {
|
||||
if (is_sdu() || is_var_len_ce()) {
|
||||
return sch_pdu::size_header_sdu(nof_bytes) + nof_bytes;
|
||||
} else {
|
||||
return nof_bytes + 1;
|
||||
}
|
||||
// All others are 1-byte headers
|
||||
return 1 + nof_bytes;
|
||||
}
|
||||
|
||||
uint32_t sch_subh::sizeof_ce(uint32_t lcid, bool is_ul)
|
||||
{
|
||||
if (is_ul) {
|
||||
switch(lcid) {
|
||||
case PHR_REPORT:
|
||||
return 1;
|
||||
case CRNTI:
|
||||
return 2;
|
||||
case TRUNC_BSR:
|
||||
return 1;
|
||||
case SHORT_BSR:
|
||||
return 1;
|
||||
case LONG_BSR:
|
||||
return 3;
|
||||
case PADDING:
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
switch(lcid) {
|
||||
case CON_RES_ID:
|
||||
return 6;
|
||||
case TA_CMD:
|
||||
return 1;
|
||||
case DRX_CMD:
|
||||
return 0;
|
||||
case PADDING:
|
||||
return 0;
|
||||
}
|
||||
if (type == SCH_SUBH_TYPE) {
|
||||
if (is_ul) {
|
||||
switch(lcid) {
|
||||
case PHR_REPORT:
|
||||
return 1;
|
||||
case CRNTI:
|
||||
return 2;
|
||||
case TRUNC_BSR:
|
||||
return 1;
|
||||
case SHORT_BSR:
|
||||
return 1;
|
||||
case LONG_BSR:
|
||||
return 3;
|
||||
case PADDING:
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
switch(lcid) {
|
||||
case CON_RES_ID:
|
||||
return 6;
|
||||
case TA_CMD:
|
||||
return 1;
|
||||
case DRX_CMD:
|
||||
return 0;
|
||||
case PADDING:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type == MCH_SUBH_TYPE) {
|
||||
switch (lcid) {
|
||||
case MCH_SCHED_INFO:
|
||||
return nof_mch_sched_ce*2;
|
||||
case PADDING:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool sch_subh::is_sdu()
|
||||
{
|
||||
return ce_type() == SDU;
|
||||
}
|
||||
|
||||
bool sch_subh::is_var_len_ce()
|
||||
{
|
||||
return (MCH_SCHED_INFO == ce_type()) && (MCH_SUBH_TYPE == type);
|
||||
}
|
||||
|
||||
uint16_t sch_subh::get_c_rnti()
|
||||
{
|
||||
if (payload) {
|
||||
|
@ -403,6 +384,7 @@ uint16_t sch_subh::get_c_rnti()
|
|||
return (uint16_t) w_payload_ce[0]<<8 | w_payload_ce[1];
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t sch_subh::get_con_res_id()
|
||||
{
|
||||
if (payload) {
|
||||
|
@ -414,6 +396,7 @@ uint64_t sch_subh::get_con_res_id()
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
float sch_subh::get_phr()
|
||||
{
|
||||
if (payload) {
|
||||
|
@ -451,6 +434,21 @@ int sch_subh::get_bsr(uint32_t buff_size[4])
|
|||
}
|
||||
}
|
||||
|
||||
bool sch_subh::get_next_mch_sched_info(uint8_t *lcid_, uint16_t *mtch_stop)
|
||||
{
|
||||
if(payload) {
|
||||
nof_mch_sched_ce = nof_bytes/2;
|
||||
if(cur_mch_sched_ce < nof_mch_sched_ce) {
|
||||
*lcid_ = (payload[cur_mch_sched_ce*2]&0xF8) >> 3;
|
||||
*mtch_stop = ((uint16_t)(payload[cur_mch_sched_ce*2]&0x07)) << 8;
|
||||
*mtch_stop += payload[cur_mch_sched_ce*2+1];
|
||||
cur_mch_sched_ce++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t sch_subh::get_ta_cmd()
|
||||
{
|
||||
if (payload) {
|
||||
|
@ -459,42 +457,49 @@ uint8_t sch_subh::get_ta_cmd()
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t sch_subh::get_sdu_lcid()
|
||||
{
|
||||
return lcid;
|
||||
}
|
||||
int sch_subh::get_payload_size()
|
||||
|
||||
|
||||
uint32_t sch_subh::get_payload_size()
|
||||
|
||||
{
|
||||
return nof_bytes;
|
||||
}
|
||||
|
||||
uint32_t sch_subh::get_header_size(bool is_last) {
|
||||
if (!is_last) {
|
||||
// For all subheaders, size can be 1, 2 or 3 bytes
|
||||
if (is_sdu()) {
|
||||
return sch_pdu::size_header_sdu(get_payload_size());
|
||||
} else {
|
||||
return 1;
|
||||
return sch_pdu::size_header_sdu(nof_bytes);
|
||||
}
|
||||
if (lcid == MCH_SCHED_INFO && type == MCH_SUBH_TYPE) {
|
||||
return sch_pdu::size_header_sdu(nof_bytes);
|
||||
}
|
||||
return 1; // All others are 1-byte
|
||||
} else {
|
||||
// Last subheader (CE or SDU) has always 1 byte header
|
||||
return 1;
|
||||
return 1; // Last subheader (CE or SDU) has always 1 byte header
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* sch_subh::get_sdu_ptr()
|
||||
{
|
||||
return payload;
|
||||
}
|
||||
|
||||
void sch_subh::set_padding(uint32_t padding_len)
|
||||
{
|
||||
lcid = PADDING;
|
||||
nof_bytes = padding_len;
|
||||
}
|
||||
|
||||
void sch_subh::set_padding()
|
||||
{
|
||||
set_padding(0);
|
||||
}
|
||||
|
||||
|
||||
bool sch_subh::set_bsr(uint32_t buff_size[4], sch_subh::cetype format)
|
||||
{
|
||||
uint32_t nonzero_lcg=0;
|
||||
|
@ -577,6 +582,20 @@ bool sch_subh::set_ta_cmd(uint8_t ta_cmd)
|
|||
}
|
||||
}
|
||||
|
||||
bool sch_subh::set_next_mch_sched_info(uint8_t lcid_, uint16_t mtch_stop)
|
||||
{
|
||||
if (((sch_pdu*)parent)->has_space_ce(2, true)) {
|
||||
w_payload_ce[nof_mch_sched_ce*2] = (lcid_&0x1F) << 3 | (uint8_t) ((mtch_stop&0x0700)>>8);
|
||||
w_payload_ce[nof_mch_sched_ce*2+1] = (uint8_t) (mtch_stop&0xff);
|
||||
nof_mch_sched_ce++;
|
||||
lcid = MCH_SCHED_INFO;
|
||||
((sch_pdu*)parent)->update_space_ce(2, true);
|
||||
nof_bytes += 2;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int sch_subh::set_sdu(uint32_t lcid_, uint32_t requested_bytes, read_pdu_interface *sdu_itf)
|
||||
{
|
||||
if (((sch_pdu*)parent)->has_space_sdu(requested_bytes)) {
|
||||
|
@ -584,17 +603,22 @@ int sch_subh::set_sdu(uint32_t lcid_, uint32_t requested_bytes, read_pdu_interfa
|
|||
|
||||
payload = ((sch_pdu*)parent)->get_current_sdu_ptr();
|
||||
// Copy data and get final number of bytes written to the MAC PDU
|
||||
uint32_t sdu_sz = sdu_itf->read_pdu(lcid, payload, requested_bytes);
|
||||
int sdu_sz = sdu_itf->read_pdu(lcid, payload, requested_bytes);
|
||||
|
||||
if (sdu_sz < 0 || sdu_sz > requested_bytes) {
|
||||
if (sdu_sz < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (sdu_sz == 0) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
// Save final number of written bytes
|
||||
nof_bytes = sdu_sz;
|
||||
|
||||
// Save final number of written bytes
|
||||
nof_bytes = sdu_sz;
|
||||
if(nof_bytes > (int32_t)requested_bytes) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
((sch_pdu*)parent)->add_sdu(nof_bytes);
|
||||
((sch_pdu*)parent)->update_space_sdu(nof_bytes);
|
||||
|
@ -627,7 +651,7 @@ void sch_subh::write_subheader(uint8_t** ptr, bool is_last)
|
|||
{
|
||||
*(*ptr) = (uint8_t) (is_last?0:(1<<5)) | ((uint8_t) lcid & 0x1f);
|
||||
*ptr += 1;
|
||||
if (is_sdu()) {
|
||||
if (is_sdu() || is_var_len_ce()) {
|
||||
// MAC SDU: R/R/E/LCID/F/L subheader
|
||||
// 2nd and 3rd octet
|
||||
if (!is_last) {
|
||||
|
@ -649,8 +673,8 @@ void sch_subh::write_payload(uint8_t** ptr)
|
|||
if (is_sdu()) {
|
||||
// SDU is written directly during subheader creation
|
||||
} else {
|
||||
nof_bytes = sizeof_ce(lcid, parent->is_ul());
|
||||
memcpy(*ptr, w_payload_ce, nof_bytes*sizeof(uint8_t));
|
||||
nof_bytes = sizeof_ce(lcid, parent->is_ul());
|
||||
memcpy(*ptr, w_payload_ce, nof_bytes*sizeof(uint8_t));
|
||||
}
|
||||
*ptr += nof_bytes;
|
||||
}
|
||||
|
@ -661,7 +685,7 @@ bool sch_subh::read_subheader(uint8_t** ptr)
|
|||
bool e_bit = (bool) (*(*ptr) & 0x20)?true:false;
|
||||
lcid = (uint8_t) *(*ptr) & 0x1f;
|
||||
*ptr += 1;
|
||||
if (is_sdu()) {
|
||||
if (is_sdu() || is_var_len_ce()) {
|
||||
if (e_bit) {
|
||||
F_bit = (bool) (*(*ptr) & 0x80)?true:false;
|
||||
nof_bytes = (uint32_t)*(*ptr) & 0x7f;
|
||||
|
@ -679,12 +703,64 @@ bool sch_subh::read_subheader(uint8_t** ptr)
|
|||
}
|
||||
return e_bit;
|
||||
}
|
||||
|
||||
void sch_subh::read_payload(uint8_t** ptr)
|
||||
{
|
||||
payload = *ptr;
|
||||
*ptr += nof_bytes;
|
||||
}
|
||||
|
||||
void sch_subh::fprint(FILE* stream)
|
||||
{
|
||||
if (is_sdu()) {
|
||||
fprintf(stream, "SDU LCHID=%d, SDU nof_bytes=%d\n", lcid, nof_bytes);
|
||||
} else if (type == SCH_SUBH_TYPE) {
|
||||
if (parent->is_ul()) {
|
||||
switch(lcid) {
|
||||
case CRNTI:
|
||||
fprintf(stream, "C-RNTI CE\n");
|
||||
break;
|
||||
case PHR_REPORT:
|
||||
fprintf(stream, "PHR\n");
|
||||
break;
|
||||
case TRUNC_BSR:
|
||||
fprintf(stream, "Truncated BSR CE\n");
|
||||
break;
|
||||
case SHORT_BSR:
|
||||
fprintf(stream, "Short BSR CE\n");
|
||||
break;
|
||||
case LONG_BSR:
|
||||
fprintf(stream, "Long BSR CE\n");
|
||||
break;
|
||||
case PADDING:
|
||||
fprintf(stream, "PADDING\n");
|
||||
}
|
||||
} else {
|
||||
switch(lcid) {
|
||||
case CON_RES_ID:
|
||||
fprintf(stream, "Contention Resolution ID CE: 0x%lx\n", get_con_res_id());
|
||||
break;
|
||||
case TA_CMD:
|
||||
fprintf(stream, "Time Advance Command CE: %d\n", get_ta_cmd());
|
||||
break;
|
||||
case DRX_CMD:
|
||||
fprintf(stream, "DRX Command CE: Not implemented\n");
|
||||
break;
|
||||
case PADDING:
|
||||
fprintf(stream, "PADDING\n");
|
||||
}
|
||||
}
|
||||
} else if (type == MCH_SUBH_TYPE) {
|
||||
switch(lcid) {
|
||||
case MCH_SCHED_INFO:
|
||||
fprintf(stream, "MCH Scheduling Info CE\n");
|
||||
break;
|
||||
case PADDING:
|
||||
fprintf(stream, "PADDING\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t sch_subh::buff_size_table(uint32_t buffer_size) {
|
||||
if (buffer_size == 0) {
|
||||
return 0;
|
||||
|
@ -712,12 +788,6 @@ uint8_t sch_subh::phr_report_table(float phr_value)
|
|||
return (uint8_t) floor(phr_value+23);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void rar_pdu::fprint(FILE* stream)
|
||||
{
|
||||
fprintf(stream, "MAC PDU for RAR. ");
|
||||
|
@ -727,26 +797,22 @@ void rar_pdu::fprint(FILE* stream)
|
|||
pdu::fprint(stream);
|
||||
}
|
||||
|
||||
|
||||
void rar_subh::fprint(FILE* stream)
|
||||
{
|
||||
fprintf(stream, "RAPID: %d, Temp C-RNTI: %d, TA: %d, UL Grant: ", preamble, temp_rnti, ta);
|
||||
srslte_vec_fprint_hex(stream, grant, 20);
|
||||
}
|
||||
|
||||
rar_pdu::rar_pdu(uint32_t max_rars_) : pdu(max_rars_)
|
||||
{
|
||||
backoff_indicator = 0;
|
||||
has_backoff_indicator = false;
|
||||
}
|
||||
|
||||
uint8_t rar_pdu::get_backoff()
|
||||
{
|
||||
return backoff_indicator;
|
||||
}
|
||||
|
||||
bool rar_pdu::has_backoff()
|
||||
{
|
||||
return has_backoff_indicator;
|
||||
}
|
||||
|
||||
void rar_pdu::set_backoff(uint8_t bi)
|
||||
{
|
||||
has_backoff_indicator = true;
|
||||
|
@ -779,7 +845,11 @@ bool rar_pdu::write_packet(uint8_t* ptr)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
void rar_subh::fprint(FILE* stream)
|
||||
{
|
||||
fprintf(stream, "RAPID: %d, Temp C-RNTI: %d, TA: %d, UL Grant: ", preamble, temp_rnti, ta);
|
||||
srslte_vec_fprint_hex(stream, grant, 20);
|
||||
}
|
||||
|
||||
void rar_subh::init()
|
||||
{
|
||||
|
@ -787,38 +857,47 @@ void rar_subh::init()
|
|||
ta = 0;
|
||||
temp_rnti = 0;
|
||||
}
|
||||
|
||||
uint32_t rar_subh::get_rapid()
|
||||
{
|
||||
return preamble;
|
||||
}
|
||||
|
||||
void rar_subh::get_sched_grant(uint8_t grant_[RAR_GRANT_LEN])
|
||||
{
|
||||
memcpy(grant_, grant, sizeof(uint8_t)*RAR_GRANT_LEN);
|
||||
}
|
||||
|
||||
uint32_t rar_subh::get_ta_cmd()
|
||||
{
|
||||
return ta;
|
||||
}
|
||||
|
||||
uint16_t rar_subh::get_temp_crnti()
|
||||
{
|
||||
return temp_rnti;
|
||||
}
|
||||
|
||||
void rar_subh::set_rapid(uint32_t rapid)
|
||||
{
|
||||
preamble = rapid;
|
||||
}
|
||||
|
||||
void rar_subh::set_sched_grant(uint8_t grant_[RAR_GRANT_LEN])
|
||||
{
|
||||
memcpy(grant, grant_, sizeof(uint8_t)*RAR_GRANT_LEN);
|
||||
}
|
||||
|
||||
void rar_subh::set_ta_cmd(uint32_t ta_)
|
||||
{
|
||||
ta = ta_;
|
||||
}
|
||||
|
||||
void rar_subh::set_temp_crnti(uint16_t temp_rnti_)
|
||||
{
|
||||
temp_rnti = temp_rnti_;
|
||||
}
|
||||
|
||||
// Section 6.2.2
|
||||
void rar_subh::write_subheader(uint8_t** ptr, bool is_last)
|
||||
{
|
||||
|
@ -866,150 +945,3 @@ bool rar_subh::read_subheader(uint8_t** ptr)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//int main()
|
||||
//{
|
||||
// /* Test 1st message: CCCH + Short BSR + PHR */
|
||||
// uint8_t buffer[10240];
|
||||
// uint8_t ccch_payload[6] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60};
|
||||
// uint32_t bsr_st[4] = {1, 2, 3, 4};
|
||||
// srsue::sch_pdu pdu(10);
|
||||
// uint8_t *ptr;
|
||||
|
||||
// printf("------- CCCH + Short BSR + PHR no padding ----------\n");
|
||||
// bzero(buffer, 10240);
|
||||
// pdu.init_tx(buffer, 11, true);
|
||||
// printf("Available space: %d\n", pdu.rem_size());
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_sdu(0,6,ccch_payload);
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_phr(10);
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_bsr(bsr_st, srsue::sch_subh::SHORT_BSR);
|
||||
// printf("Remaining space: %d\n", pdu.rem_size());
|
||||
// ptr = pdu.write_packet();
|
||||
// srslte_vec_fprint_byte(stdout, ptr, pdu.get_pdu_len());
|
||||
// printf("\n");
|
||||
|
||||
// /* Test single SDU: SDU 15 + 1 byte header */
|
||||
// printf("------- Single SDU no padding ----------\n");
|
||||
// uint8_t dlsch_payload[15] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
|
||||
// bzero(buffer, 10240);
|
||||
// pdu.init_tx(buffer, 16, true);
|
||||
// printf("Available space: %d\n", pdu.rem_size());
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_sdu(1, 15, dlsch_payload);
|
||||
// printf("Remaining space: %d\n", pdu.rem_size());
|
||||
// ptr = pdu.write_packet();
|
||||
// srslte_vec_fprint_byte(stdout, ptr, pdu.get_pdu_len());
|
||||
// printf("\n");
|
||||
|
||||
// /* Test multiple SDU + multiword padding: SDU 8 + SDU 2 byte*/
|
||||
// printf("------- Multiple SDU + multiword padding ----------\n");
|
||||
// uint8_t dlsch_payload1[8] = {1,2,3,4,5,6,7,8};
|
||||
// uint8_t dlsch_payload2[2] = {0xA, 0xB};
|
||||
// bzero(buffer, 10240);
|
||||
// pdu.init_tx(buffer, 18, true);
|
||||
// printf("Available space: %d\n", pdu.rem_size());
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_sdu(2, 8, dlsch_payload1);
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_sdu(3, 2, dlsch_payload2);
|
||||
// printf("Remaining space: %d\n", pdu.rem_size());
|
||||
// ptr = pdu.write_packet();
|
||||
// srslte_vec_fprint_byte(stdout, ptr, pdu.get_pdu_len());
|
||||
// printf("\n");
|
||||
|
||||
// printf("------- Multiple SDU + 2word padding ----------\n");
|
||||
// bzero(buffer, 10240);
|
||||
// pdu.init_tx(buffer, 15, true);
|
||||
// printf("Available space: %d\n", pdu.rem_size());
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_sdu(2, 8, dlsch_payload1);
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_sdu(3, 2, dlsch_payload2);
|
||||
// printf("Remaining space: %d\n", pdu.rem_size());
|
||||
// ptr = pdu.write_packet();
|
||||
// srslte_vec_fprint_byte(stdout, ptr, pdu.get_pdu_len());
|
||||
// printf("\n");
|
||||
|
||||
// printf("------- Multiple SDU + 1word padding ----------\n");
|
||||
// bzero(buffer, 10240);
|
||||
// pdu.init_tx(buffer, 14, true);
|
||||
// printf("Available space: %d\n", pdu.rem_size());
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_sdu(2, 8, dlsch_payload1);
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_sdu(3, 2, dlsch_payload2);
|
||||
// printf("Remaining space: %d\n", pdu.rem_size());
|
||||
// ptr = pdu.write_packet();
|
||||
// srslte_vec_fprint_byte(stdout, ptr, pdu.get_pdu_len());
|
||||
// printf("\n");
|
||||
|
||||
// printf("------- Multiple SDU + 0word padding ----------\n");
|
||||
// bzero(buffer, 10240);
|
||||
// pdu.init_tx(buffer, 13, true);
|
||||
// printf("Available space: %d\n", pdu.rem_size());
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_sdu(2, 8, dlsch_payload1);
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_sdu(3, 2, dlsch_payload2);
|
||||
// printf("Remaining space: %d\n", pdu.rem_size());
|
||||
// ptr = pdu.write_packet();
|
||||
// srslte_vec_fprint_byte(stdout, ptr, pdu.get_pdu_len());
|
||||
// printf("\n");
|
||||
|
||||
// printf("------- Multiple SDU + no space ----------\n");
|
||||
// bzero(buffer, 10240);
|
||||
// pdu.init_tx(buffer, 12, true);
|
||||
// printf("Available space: %d\n", pdu.rem_size());
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_sdu(2, 8, dlsch_payload1);
|
||||
// pdu.new_subh();
|
||||
// if (pdu.get()->set_sdu(3, 2, dlsch_payload2) < 0) {
|
||||
// pdu.del_subh();
|
||||
// }
|
||||
// printf("Remaining space: %d\n", pdu.rem_size());
|
||||
// ptr = pdu.write_packet();
|
||||
// srslte_vec_fprint_byte(stdout, ptr, pdu.get_pdu_len());
|
||||
// printf("\n");
|
||||
|
||||
// /* CE only */
|
||||
// printf("------- CE only ----------\n");
|
||||
// bzero(buffer, 10240);
|
||||
// pdu.init_tx(buffer, 125, true);
|
||||
// printf("Available space: %d\n", pdu.rem_size());
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_phr(15);
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_bsr(bsr_st, srsue::sch_subh::SHORT_BSR);
|
||||
// printf("Remaining space: %d\n", pdu.rem_size());
|
||||
// ptr = pdu.write_packet();
|
||||
// srslte_vec_fprint_byte(stdout, ptr, pdu.get_pdu_len());
|
||||
// printf("\n");
|
||||
|
||||
// /* Another test */
|
||||
// printf("------- Another test ----------\n");
|
||||
// uint8_t dlsch_payload3[602];
|
||||
// bzero(buffer, 10240);
|
||||
// pdu.init_tx(buffer, 75, true);
|
||||
// printf("Available space: %d\n", pdu.rem_size());
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_bsr(bsr_st, srsue::sch_subh::SHORT_BSR);
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_sdu(3, 2, dlsch_payload3);
|
||||
// pdu.new_subh();
|
||||
// pdu.get()->set_sdu(3, 66, dlsch_payload3);
|
||||
// pdu.new_subh();
|
||||
// printf("Remaining space: %d\n", pdu.rem_size());
|
||||
// ptr = pdu.write_packet();
|
||||
// //srslte_vec_fprint_byte(stdout, ptr, pdu.get_pdu_len());
|
||||
// printf("\n");
|
||||
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ uint8_t* pdu_queue::request(uint32_t len)
|
|||
fprintf(stderr, "Error request buffer of invalid size %d. Max bytes %d\n", len, MAX_PDU_LEN);
|
||||
return NULL;
|
||||
}
|
||||
pdu_t *pdu = pool.allocate();
|
||||
pdu_t *pdu = pool.allocate("pdu_queue::request");
|
||||
if (!pdu) {
|
||||
if (log_h) {
|
||||
log_h->error("Not enough buffers for MAC PDU\n");
|
||||
|
@ -74,12 +74,13 @@ void pdu_queue::deallocate(uint8_t* pdu)
|
|||
* This function enqueues the packet and returns quicly because ACK
|
||||
* deadline is important here.
|
||||
*/
|
||||
void pdu_queue::push(uint8_t *ptr, uint32_t len, uint32_t tstamp)
|
||||
void pdu_queue::push(uint8_t *ptr, uint32_t len, channel_t channel, uint32_t tstamp)
|
||||
{
|
||||
if (ptr) {
|
||||
pdu_t *pdu = (pdu_t*) ptr;
|
||||
pdu->len = len;
|
||||
pdu->tstamp = tstamp;
|
||||
pdu->channel = channel;
|
||||
pdu_q.push(pdu);
|
||||
} else {
|
||||
log_h->warning("Error pushing pdu: ptr is empty\n");
|
||||
|
@ -88,15 +89,12 @@ void pdu_queue::push(uint8_t *ptr, uint32_t len, uint32_t tstamp)
|
|||
|
||||
bool pdu_queue::process_pdus()
|
||||
{
|
||||
bool have_data = false;
|
||||
uint32_t cnt = 0;
|
||||
pdu_t *pdu;
|
||||
bool have_data = false;
|
||||
uint32_t cnt = 0;
|
||||
pdu_t *pdu;
|
||||
while(pdu_q.try_pop(&pdu)) {
|
||||
if (callback) {
|
||||
callback->process_pdu(pdu->ptr, pdu->len, pdu->tstamp);
|
||||
}
|
||||
if (!pool.deallocate(pdu)) {
|
||||
log_h->warning("Error deallocating from buffer pool in process_pdus(): buffer not created in this pool.\n");
|
||||
callback->process_pdu(pdu->ptr, pdu->len, pdu->channel, pdu->tstamp);
|
||||
}
|
||||
cnt++;
|
||||
have_data = true;
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsUE library.
|
||||
*
|
||||
* srsUE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsUE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include "srslte/srslte.h"
|
||||
#include "srslte/common/pcap.h"
|
||||
#include "srslte/common/rlc_pcap.h"
|
||||
|
||||
namespace srslte {
|
||||
|
||||
void rlc_pcap::enable(bool en)
|
||||
{
|
||||
enable_write = true;
|
||||
}
|
||||
void rlc_pcap::open(const char* filename, uint32_t ue_id)
|
||||
{
|
||||
fprintf(stdout, "Opening RLC PCAP with DLT=%d\n", RLC_LTE_DLT);
|
||||
pcap_file = LTE_PCAP_Open(RLC_LTE_DLT, filename);
|
||||
this->ue_id = ue_id;
|
||||
enable_write = true;
|
||||
}
|
||||
void rlc_pcap::close()
|
||||
{
|
||||
fprintf(stdout, "Saving RLC PCAP file\n");
|
||||
LTE_PCAP_Close(pcap_file);
|
||||
}
|
||||
|
||||
void rlc_pcap::set_ue_id(uint16_t ue_id) {
|
||||
this->ue_id = ue_id;
|
||||
}
|
||||
|
||||
void rlc_pcap::pack_and_write(uint8_t* pdu, uint32_t pdu_len_bytes, uint8_t mode, uint8_t direction, uint8_t priority, uint8_t seqnumberlength, uint16_t ueid, uint16_t channel_type, uint16_t channel_id)
|
||||
{
|
||||
if (enable_write) {
|
||||
RLC_Context_Info_t context;
|
||||
context.rlcMode = mode;
|
||||
context.direction = direction;
|
||||
context.priority = priority;
|
||||
context.sequenceNumberLength = seqnumberlength;
|
||||
context.ueid = ueid;
|
||||
context.channelType = channel_type;
|
||||
context.channelId = channel_id;
|
||||
context.pduLength = pdu_len_bytes;
|
||||
if (pdu) {
|
||||
LTE_PCAP_RLC_WritePDU(pcap_file, &context, pdu, pdu_len_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rlc_pcap::write_dl_am_ccch(uint8_t* pdu, uint32_t pdu_len_bytes)
|
||||
{
|
||||
uint8_t priority = 0;
|
||||
uint8_t seqnumberlength = 0; // normal length of 10bit
|
||||
uint8_t channel_id = 0;
|
||||
pack_and_write(pdu, pdu_len_bytes, RLC_AM_MODE, DIRECTION_DOWNLINK, priority, seqnumberlength, ue_id, CHANNEL_TYPE_CCCH, channel_id);
|
||||
}
|
||||
|
||||
void rlc_pcap::write_ul_am_ccch(uint8_t* pdu, uint32_t pdu_len_bytes)
|
||||
{
|
||||
uint8_t priority = 0;
|
||||
uint8_t seqnumberlength = 0; // normal length of 10bit
|
||||
uint8_t channel_id = 0;
|
||||
pack_and_write(pdu, pdu_len_bytes, RLC_AM_MODE, DIRECTION_UPLINK, priority, seqnumberlength, ue_id, CHANNEL_TYPE_CCCH, channel_id);
|
||||
}
|
||||
|
||||
}
|
|
@ -29,6 +29,13 @@
|
|||
#include "srslte/common/liblte_security.h"
|
||||
#include "srslte/common/snow_3g.h"
|
||||
|
||||
#ifdef HAVE_MBEDTLS
|
||||
#include "mbedtls/md5.h"
|
||||
#endif
|
||||
#ifdef HAVE_POLARSSL
|
||||
#include "polarssl/md5.h"
|
||||
#endif
|
||||
|
||||
namespace srslte {
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -126,7 +133,7 @@ uint8_t security_generate_k_up( uint8_t *k_enb,
|
|||
|
||||
uint8_t security_128_eia1( uint8_t *key,
|
||||
uint32_t count,
|
||||
uint8_t bearer,
|
||||
uint32_t bearer,
|
||||
uint8_t direction,
|
||||
uint8_t *msg,
|
||||
uint32_t msg_len,
|
||||
|
@ -151,7 +158,7 @@ uint8_t security_128_eia1( uint8_t *key,
|
|||
|
||||
uint8_t security_128_eia2( uint8_t *key,
|
||||
uint32_t count,
|
||||
uint8_t bearer,
|
||||
uint32_t bearer,
|
||||
uint8_t direction,
|
||||
uint8_t *msg,
|
||||
uint32_t msg_len,
|
||||
|
@ -166,6 +173,19 @@ uint8_t security_128_eia2( uint8_t *key,
|
|||
mac);
|
||||
}
|
||||
|
||||
uint8_t security_md5(const uint8_t *input, size_t len, uint8_t *output)
|
||||
{
|
||||
memset(output, 0x00, 16);
|
||||
#ifdef HAVE_MBEDTLS
|
||||
mbedtls_md5(input, len, output);
|
||||
#endif // HAVE_MBEDTLS
|
||||
#ifdef HAVE_POLARSSL
|
||||
md5(input, len, output);
|
||||
#endif
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Encryption / Decryption
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -81,7 +81,6 @@ thread_pool::thread_pool(uint32_t max_workers_) :
|
|||
status(max_workers_),
|
||||
cvar(max_workers_),
|
||||
mutex(max_workers_)
|
||||
|
||||
{
|
||||
max_workers = max_workers_;
|
||||
for (uint32_t i=0;i<max_workers;i++) {
|
||||
|
|
|
@ -45,6 +45,8 @@ int srslte_agc_init_acc(srslte_agc_t *q, srslte_agc_mode_t mode, uint32_t nof_fr
|
|||
bzero(q, sizeof(srslte_agc_t));
|
||||
q->mode = mode;
|
||||
q->nof_frames = nof_frames;
|
||||
q->max_gain = 90.0;
|
||||
q->min_gain = 0.0;
|
||||
if (nof_frames > 0) {
|
||||
q->y_tmp = srslte_vec_malloc(sizeof(float) * nof_frames);
|
||||
if (!q->y_tmp) {
|
||||
|
@ -86,6 +88,13 @@ void srslte_agc_reset(srslte_agc_t *q) {
|
|||
}
|
||||
}
|
||||
|
||||
void srslte_agc_set_gain_range(srslte_agc_t *q, double min_gain, double max_gain) {
|
||||
if (q) {
|
||||
q->min_gain = min_gain;
|
||||
q->max_gain = max_gain;
|
||||
}
|
||||
}
|
||||
|
||||
void srslte_agc_set_bandwidth(srslte_agc_t *q, float bandwidth) {
|
||||
q->bandwidth = bandwidth;
|
||||
}
|
||||
|
@ -116,19 +125,23 @@ void srslte_agc_lock(srslte_agc_t *q, bool enable) {
|
|||
|
||||
void srslte_agc_process(srslte_agc_t *q, cf_t *signal, uint32_t len) {
|
||||
if (!q->lock) {
|
||||
float gain_db = 10*log10(q->gain);
|
||||
float gain_uhd_db = 50.0;
|
||||
//float gain_uhd = 1.0;
|
||||
double gain_db = 10.0 * log10(q->gain);
|
||||
double gain_uhd_db = 50.0;
|
||||
|
||||
float y = 0;
|
||||
// Apply current gain to input signal
|
||||
if (!q->uhd_handler) {
|
||||
srslte_vec_sc_prod_cfc(signal, q->gain, signal, len);
|
||||
} else {
|
||||
if (gain_db < 0) {
|
||||
gain_db = 5.0;
|
||||
}
|
||||
if (isinf(gain_db) || isnan(gain_db)) {
|
||||
gain_db = 40.0;
|
||||
if (gain_db < q->min_gain) {
|
||||
gain_db = q->min_gain + 5.0;
|
||||
INFO("Warning: Rx signal strength is too high. Forcing minimum Rx gain %.2fdB\n", gain_db);
|
||||
} else if (gain_db > q->max_gain) {
|
||||
gain_db = q->max_gain;
|
||||
INFO("Warning: Rx signal strength is too weak. Forcing maximum Rx gain %.2fdB\n", gain_db);
|
||||
} else if (isinf(gain_db) || isnan(gain_db)) {
|
||||
gain_db = (q->min_gain + q->max_gain) / 2.0;
|
||||
INFO("Warning: AGC went to an unknown state. Setting Rx gain to %.2fdB\n", gain_db);
|
||||
} else {
|
||||
gain_uhd_db = q->set_gain_callback(q->uhd_handler, gain_db);
|
||||
q->gain = pow(10, gain_uhd_db/10);
|
||||
|
|
|
@ -124,7 +124,7 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, uint32_t max_prb)
|
|||
perror("malloc");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
|
||||
q->pilot_recv_signal = srslte_vec_malloc(sizeof(cf_t) * pilot_vec_size);
|
||||
if (!q->pilot_recv_signal) {
|
||||
perror("malloc");
|
||||
|
@ -154,7 +154,8 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, uint32_t max_prb)
|
|||
q->noise_alg = SRSLTE_NOISE_ALG_REFS;
|
||||
|
||||
q->rsrp_neighbour = false;
|
||||
|
||||
q->average_subframe = false;
|
||||
q->smooth_filter_auto = false;
|
||||
q->smooth_filter_len = 3;
|
||||
srslte_chest_dl_set_smooth_filter3_coeff(q, 0.1);
|
||||
|
||||
|
@ -211,9 +212,12 @@ int srslte_chest_dl_set_mbsfn_area_id(srslte_chest_dl_t *q, uint16_t mbsfn_area_
|
|||
if (mbsfn_area_id < SRSLTE_MAX_MBSFN_AREA_IDS) {
|
||||
if(!q->mbsfn_refs[mbsfn_area_id]) {
|
||||
q->mbsfn_refs[mbsfn_area_id] = calloc(1, sizeof(srslte_refsignal_t));
|
||||
if(srslte_refsignal_mbsfn_init(q->mbsfn_refs[mbsfn_area_id], q->cell.nof_prb)) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
if(q->mbsfn_refs[mbsfn_area_id]) {
|
||||
if(srslte_refsignal_mbsfn_init(q->mbsfn_refs[mbsfn_area_id], q->cell, mbsfn_area_id)) {
|
||||
if(srslte_refsignal_mbsfn_set_cell(q->mbsfn_refs[mbsfn_area_id], q->cell, mbsfn_area_id)) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -263,48 +267,72 @@ int srslte_chest_dl_set_cell(srslte_chest_dl_t *q, srslte_cell_t cell)
|
|||
/* Uses the difference between the averaged and non-averaged pilot estimates */
|
||||
static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id, srslte_sf_t ch_mode)
|
||||
{
|
||||
int nref=SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id);
|
||||
const float weight = 1.0f;
|
||||
float sum_power = 0.0f;
|
||||
uint32_t count = 0;
|
||||
uint32_t npilots = (ch_mode == SRSLTE_SF_MBSFN)?SRSLTE_REFSIGNAL_NUM_SF_MBSFN(q->cell.nof_prb, port_id):SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id);
|
||||
uint32_t nsymbols = (ch_mode == SRSLTE_SF_MBSFN) ? srslte_refsignal_mbsfn_nof_symbols() : srslte_refsignal_cs_nof_symbols(port_id);
|
||||
uint32_t nref = npilots / nsymbols;
|
||||
uint32_t fidx = (ch_mode == SRSLTE_SF_MBSFN)?srslte_refsignal_mbsfn_fidx(1):srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0);
|
||||
|
||||
if (q->average_subframe) {
|
||||
if (ch_mode == SRSLTE_SF_MBSFN) {
|
||||
nref /= 4;
|
||||
} else {
|
||||
nref /= 2;
|
||||
}
|
||||
cf_t *input2d[nsymbols + 2];
|
||||
cf_t *tmp_noise = q->tmp_noise;
|
||||
|
||||
for (int i = 0; i < nsymbols; i++) {
|
||||
input2d[i + 1] = &q->pilot_estimates[i * nref];
|
||||
}
|
||||
|
||||
/* Substract noisy pilot estimates */
|
||||
srslte_vec_sub_ccc(q->pilot_estimates_average, q->pilot_estimates, q->tmp_noise, nref);
|
||||
|
||||
#ifdef FREQ_SEL_SNR
|
||||
/* Compute frequency-selective SNR */
|
||||
srslte_vec_abs_square_cf(q->tmp_noise, q->snr_vector, nref);
|
||||
srslte_vec_abs_square_cf(q->pilot_estimates, q->pilot_power, nref);
|
||||
srslte_vec_div_fff(q->pilot_power, q->snr_vector, q->snr_vector, nref);
|
||||
|
||||
srslte_vec_fprint_f(stdout, q->snr_vector, nref);
|
||||
#endif
|
||||
|
||||
/* Compute average power. Normalized for filter len 3 using matlab */
|
||||
float norm = 1;
|
||||
if (q->average_subframe) {
|
||||
norm = 32;
|
||||
input2d[0] = &q->tmp_noise[nref];
|
||||
if (nsymbols > 3) {
|
||||
srslte_vec_sc_prod_cfc(input2d[2], 2.0f, input2d[0], nref);
|
||||
srslte_vec_sub_ccc(input2d[0], input2d[4], input2d[0], nref);
|
||||
} else {
|
||||
if (q->smooth_filter_len == 3) {
|
||||
float a = q->smooth_filter[0];
|
||||
float norm3 = 6.143*a*a+0.04859*a-0.002774;
|
||||
norm /= norm3;
|
||||
}
|
||||
srslte_vec_sc_prod_cfc(input2d[2], 1.0f, input2d[0], nref);
|
||||
}
|
||||
float power = norm*srslte_vec_avg_power_cf(q->tmp_noise, nref);
|
||||
return power;
|
||||
|
||||
input2d[nsymbols + 1] = &q->tmp_noise[nref * 2];
|
||||
if (nsymbols > 3) {
|
||||
srslte_vec_sc_prod_cfc(input2d[nsymbols - 1], 2.0f, input2d[nsymbols + 1], nref);
|
||||
srslte_vec_sub_ccc(input2d[nsymbols + 1], input2d[nsymbols - 3], input2d[nsymbols + 1], nref);
|
||||
} else {
|
||||
srslte_vec_sc_prod_cfc(input2d[nsymbols - 1], 1.0f, input2d[nsymbols + 1], nref);
|
||||
}
|
||||
|
||||
for (int i = 1; i < nsymbols + 1; i++) {
|
||||
uint32_t offset = ((fidx < 3) ^ (i & 1)) ? 0 : 1;
|
||||
srslte_vec_sc_prod_cfc(input2d[i], weight, tmp_noise, nref);
|
||||
|
||||
srslte_vec_sum_ccc(&input2d[i - 1][0], &tmp_noise[offset], &tmp_noise[offset], nref - offset);
|
||||
srslte_vec_sum_ccc(&input2d[i - 1][1 - offset], &tmp_noise[0], &tmp_noise[0], nref + offset - 1);
|
||||
if (offset) {
|
||||
tmp_noise[0] += 2.0f * input2d[i - 1][0] - input2d[i - 1][1];
|
||||
} else {
|
||||
tmp_noise[nref - 1] += 2.0f * input2d[i - 1][nref - 2] - input2d[i - 1][nref - 1];
|
||||
}
|
||||
|
||||
srslte_vec_sum_ccc(&input2d[i + 1][0], &tmp_noise[offset], &tmp_noise[offset], nref - offset);
|
||||
srslte_vec_sum_ccc(&input2d[i + 1][1 - offset], &tmp_noise[0], &tmp_noise[0], nref + offset - 1);
|
||||
if (offset) {
|
||||
tmp_noise[0] += 2.0f * input2d[i + 1][0] - input2d[i + 1][1];
|
||||
} else {
|
||||
tmp_noise[nref - 1] += 2.0f * input2d[i + 1][nref - 2] - input2d[i + 1][nref - 1];
|
||||
}
|
||||
|
||||
srslte_vec_sc_prod_cfc(tmp_noise, 1.0f / (weight + 4.0f), tmp_noise, nref);
|
||||
|
||||
srslte_vec_sub_ccc(input2d[i], tmp_noise, tmp_noise, nref);
|
||||
sum_power = srslte_vec_avg_power_cf(tmp_noise, nref);
|
||||
count++;
|
||||
}
|
||||
|
||||
return sum_power / (float) count * sqrtf(weight + 4.0f);
|
||||
}
|
||||
|
||||
static float estimate_noise_pss(srslte_chest_dl_t *q, cf_t *input, cf_t *ce)
|
||||
{
|
||||
/* Get PSS from received signal */
|
||||
srslte_pss_get_slot(input, q->tmp_pss, q->cell.nof_prb, q->cell.cp);
|
||||
|
||||
|
||||
/* Get channel estimates for PSS position */
|
||||
srslte_pss_get_slot(ce, q->tmp_pss_noisy, q->cell.nof_prb, q->cell.cp);
|
||||
|
||||
|
@ -313,7 +341,7 @@ static float estimate_noise_pss(srslte_chest_dl_t *q, cf_t *input, cf_t *ce)
|
|||
|
||||
/* Substract received signal */
|
||||
srslte_vec_sub_ccc(q->tmp_pss_noisy, q->tmp_pss, q->tmp_pss_noisy, SRSLTE_PSS_LEN);
|
||||
|
||||
|
||||
/* Compute average power */
|
||||
float power = q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_pss_noisy, SRSLTE_PSS_LEN)/sqrt(2);
|
||||
return power;
|
||||
|
@ -322,14 +350,14 @@ static float estimate_noise_pss(srslte_chest_dl_t *q, cf_t *input, cf_t *ce)
|
|||
/* Uses the 5 empty transmitted SC before and after the SSS and PSS sequences for noise estimation */
|
||||
static float estimate_noise_empty_sc(srslte_chest_dl_t *q, cf_t *input) {
|
||||
int k_sss = (SRSLTE_CP_NSYMB(q->cell.cp) - 2) * q->cell.nof_prb * SRSLTE_NRE + q->cell.nof_prb * SRSLTE_NRE / 2 - 31;
|
||||
float noise_power = 0;
|
||||
float noise_power = 0;
|
||||
noise_power += srslte_vec_avg_power_cf(&input[k_sss-5], 5); // 5 empty SC before SSS
|
||||
noise_power += srslte_vec_avg_power_cf(&input[k_sss+62], 5); // 5 empty SC after SSS
|
||||
int k_pss = (SRSLTE_CP_NSYMB(q->cell.cp) - 1) * q->cell.nof_prb * SRSLTE_NRE + q->cell.nof_prb * SRSLTE_NRE / 2 - 31;
|
||||
noise_power += srslte_vec_avg_power_cf(&input[k_pss-5], 5); // 5 empty SC before PSS
|
||||
noise_power += srslte_vec_avg_power_cf(&input[k_pss+62], 5); // 5 empty SC after PSS
|
||||
|
||||
return noise_power;
|
||||
|
||||
return noise_power;
|
||||
}
|
||||
|
||||
#define cesymb(i) ce[SRSLTE_RE_IDX(q->cell.nof_prb,i,0)]
|
||||
|
@ -362,11 +390,12 @@ static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t
|
|||
}
|
||||
} else {
|
||||
if (q->average_subframe) {
|
||||
fidx_offset = SRSLTE_MIN(srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0),
|
||||
srslte_refsignal_cs_fidx(q->cell, 1, port_id, 0));
|
||||
srslte_interp_linear_offset(&q->srslte_interp_lin_3, &pilot_estimates[q->cell.nof_prb * l],
|
||||
&ce[srslte_refsignal_cs_nsymbol(l, q->cell.cp, port_id) * q->cell.nof_prb
|
||||
* SRSLTE_NRE], fidx_offset, SRSLTE_NRE / 4 - fidx_offset);
|
||||
fidx_offset = q->cell.id % 3;
|
||||
srslte_interp_linear_offset(&q->srslte_interp_lin_3,
|
||||
pilot_estimates,
|
||||
ce,
|
||||
fidx_offset,
|
||||
SRSLTE_NRE / 4 - fidx_offset);
|
||||
} else {
|
||||
fidx_offset = srslte_refsignal_cs_fidx(q->cell, l, port_id, 0);
|
||||
srslte_interp_linear_offset(&q->srslte_interp_lin, &pilot_estimates[2 * q->cell.nof_prb * l],
|
||||
|
@ -379,7 +408,7 @@ static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t
|
|||
/* Now interpolate in the time domain between symbols */
|
||||
if (q->average_subframe) {
|
||||
// If we average per subframe, just copy the estimates in the time domain
|
||||
for (l=0;l<2*SRSLTE_CP_NSYMB(q->cell.cp);l++) {
|
||||
for (l=1;l<2*SRSLTE_CP_NSYMB(q->cell.cp);l++) {
|
||||
memcpy(&ce[l*SRSLTE_NRE*q->cell.nof_prb], ce, sizeof(cf_t)*SRSLTE_NRE*q->cell.nof_prb);
|
||||
}
|
||||
} else {
|
||||
|
@ -443,6 +472,54 @@ void srslte_chest_dl_set_smooth_filter3_coeff(srslte_chest_dl_t* q, float w)
|
|||
q->smooth_filter[1] = 1-2*w;
|
||||
}
|
||||
|
||||
void srslte_chest_dl_set_smooth_filter_gauss(srslte_chest_dl_t* q, uint32_t order, float std_dev)
|
||||
{
|
||||
const uint32_t filterlen = order + 1;
|
||||
const int center = (filterlen - 1) / 2;
|
||||
float *filter = q->smooth_filter;
|
||||
float norm_p = 0.0f;
|
||||
|
||||
if (filterlen) {
|
||||
|
||||
for (int i = 0; i < filterlen; i++) {
|
||||
filter[i] = expf(-powf(i - center, 2) / (2.0f * powf(std_dev, 2)));
|
||||
norm_p += powf(filter[i], 2);
|
||||
}
|
||||
|
||||
const float norm = srslte_vec_acc_ff(filter, filterlen);
|
||||
|
||||
srslte_vec_sc_prod_fff(filter, 1.0f / norm, filter, filterlen);
|
||||
q->smooth_filter_len = filterlen;
|
||||
}
|
||||
}
|
||||
|
||||
void srslte_chest_dl_set_smooth_filter_auto(srslte_chest_dl_t *q, bool enable) {
|
||||
q->smooth_filter_auto = enable;
|
||||
}
|
||||
|
||||
uint32_t srslte_chest_dl_interleave_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *tmp, cf_t *output, uint32_t port_id, srslte_sf_t ch_mode) {
|
||||
uint32_t nsymbols = (ch_mode == SRSLTE_SF_MBSFN)?srslte_refsignal_mbsfn_nof_symbols(port_id):srslte_refsignal_cs_nof_symbols(port_id);
|
||||
uint32_t nref = (ch_mode == SRSLTE_SF_MBSFN)?6*q->cell.nof_prb:2*q->cell.nof_prb;
|
||||
uint32_t fidx = (ch_mode == SRSLTE_SF_MBSFN)?srslte_refsignal_mbsfn_fidx(1):srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0);
|
||||
|
||||
if (fidx < 3) {
|
||||
srslte_vec_interleave(input, &input[nref], tmp, nref);
|
||||
for (int l = 2; l < nsymbols - 1; l += 2) {
|
||||
srslte_vec_interleave_add(&input[l * nref], &input[(l + 1) * nref], tmp, nref);
|
||||
}
|
||||
} else {
|
||||
srslte_vec_interleave(&input[nref], input, tmp, nref);
|
||||
for (int l = 2; l < nsymbols - 1; l += 2) {
|
||||
srslte_vec_interleave_add(&input[(l + 1) * nref], &input[l * nref], tmp, nref);
|
||||
}
|
||||
}
|
||||
|
||||
nref *= 2;
|
||||
srslte_vec_sc_prod_cfc(tmp, 2.0f / nsymbols, output, nref);
|
||||
|
||||
return nref;
|
||||
}
|
||||
|
||||
static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint32_t port_id, srslte_sf_t ch_mode) {
|
||||
uint32_t nsymbols = (ch_mode == SRSLTE_SF_MBSFN)?srslte_refsignal_mbsfn_nof_symbols(port_id):srslte_refsignal_cs_nof_symbols(port_id);
|
||||
uint32_t nref = (ch_mode == SRSLTE_SF_MBSFN)?6*q->cell.nof_prb:2*q->cell.nof_prb;
|
||||
|
@ -476,9 +553,16 @@ static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t skip = (ch_mode == SRSLTE_SF_MBSFN)?2*q->cell.nof_prb:0;
|
||||
|
||||
if(ch_mode == SRSLTE_SF_MBSFN){
|
||||
memcpy(&output[0],&input[0],skip*sizeof(cf_t));
|
||||
}
|
||||
|
||||
// Average in the frequency domain
|
||||
for (int l=0;l<nsymbols;l++) {
|
||||
srslte_conv_same_cf(&input[l*nref], q->smooth_filter, &output[l*nref], nref, q->smooth_filter_len);
|
||||
srslte_conv_same_cf(&input[l*nref + skip], q->smooth_filter, &output[l*nref + skip], nref, q->smooth_filter_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -523,7 +607,16 @@ void chest_interpolate_noise_est(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, ui
|
|||
q->cfo = chest_estimate_cfo(q);
|
||||
}
|
||||
|
||||
/* Estimate noise */
|
||||
if (q->noise_alg == SRSLTE_NOISE_ALG_REFS) {
|
||||
q->noise_estimate[rxant_id][port_id] = estimate_noise_pilots(q, port_id, ch_mode);
|
||||
}
|
||||
|
||||
if (ce != NULL) {
|
||||
if (q->smooth_filter_auto) {
|
||||
srslte_chest_dl_set_smooth_filter_gauss(q, 4, q->noise_estimate[rxant_id][port_id] * 200.0f);
|
||||
}
|
||||
|
||||
/* Smooth estimates (if applicable) and interpolate */
|
||||
if (q->smooth_filter_len == 0 || (q->smooth_filter_len == 3 && q->smooth_filter[0] == 0)) {
|
||||
interpolate_pilots(q, q->pilot_estimates, ce, port_id, ch_mode);
|
||||
|
@ -533,13 +626,11 @@ void chest_interpolate_noise_est(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, ui
|
|||
}
|
||||
|
||||
/* Estimate noise power */
|
||||
if (q->noise_alg == SRSLTE_NOISE_ALG_REFS && q->smooth_filter_len > 0) {
|
||||
q->noise_estimate[rxant_id][port_id] = estimate_noise_pilots(q, port_id, ch_mode);
|
||||
} else if (q->noise_alg == SRSLTE_NOISE_ALG_PSS) {
|
||||
if (q->noise_alg == SRSLTE_NOISE_ALG_PSS) {
|
||||
if (sf_idx == 0 || sf_idx == 5) {
|
||||
q->noise_estimate[rxant_id][port_id] = estimate_noise_pss(q, input, ce);
|
||||
}
|
||||
} else {
|
||||
} else if (q->noise_alg != SRSLTE_NOISE_ALG_REFS) {
|
||||
if (sf_idx == 0 || sf_idx == 5) {
|
||||
q->noise_estimate[rxant_id][port_id] = estimate_noise_empty_sc(q, input);
|
||||
}
|
||||
|
@ -580,11 +671,10 @@ int srslte_chest_dl_estimate_port_mbsfn(srslte_chest_dl_t *q, cf_t *input, cf_t
|
|||
srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->csr_refs.pilots[port_id/2][sf_idx],
|
||||
q->pilot_estimates, (2*q->cell.nof_prb));
|
||||
|
||||
srslte_vec_prod_conj_ccc(q->pilot_recv_signal+(2*q->cell.nof_prb), q->mbsfn_refs[mbsfn_area_id]->pilots[port_id/2][sf_idx],
|
||||
q->pilot_estimates+(2*q->cell.nof_prb), SRSLTE_REFSIGNAL_NUM_SF_MBSFN(q->cell.nof_prb, port_id)-(2*q->cell.nof_prb));
|
||||
srslte_vec_prod_conj_ccc(&q->pilot_recv_signal[(2*q->cell.nof_prb)], q->mbsfn_refs[mbsfn_area_id]->pilots[port_id/2][sf_idx],
|
||||
&q->pilot_estimates[(2*q->cell.nof_prb)], SRSLTE_REFSIGNAL_NUM_SF_MBSFN(q->cell.nof_prb, port_id)-(2*q->cell.nof_prb));
|
||||
|
||||
|
||||
|
||||
chest_interpolate_noise_est(q, input, ce, sf_idx, port_id, rxant_id, SRSLTE_SF_MBSFN);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -286,8 +286,8 @@ int srslte_chest_ul_estimate(srslte_chest_ul_t *q, cf_t *input, cf_t *ce,
|
|||
if (ce != NULL) {
|
||||
if (q->smooth_filter_len > 0) {
|
||||
average_pilots(q, q->pilot_estimates, ce, nrefs_sym, n_prb);
|
||||
interpolate_pilots(q, ce, nrefs_sym, n_prb);
|
||||
|
||||
interpolate_pilots(q, ce, nrefs_sym, n_prb);
|
||||
|
||||
/* If averaging, compute noise from difference between received and averaged estimates */
|
||||
q->noise_estimate = estimate_noise_pilots(q, ce, nrefs_sym, n_prb);
|
||||
} else {
|
||||
|
@ -301,8 +301,7 @@ int srslte_chest_ul_estimate(srslte_chest_ul_t *q, cf_t *input, cf_t *ce,
|
|||
q->noise_estimate = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Estimate received pilot power
|
||||
// Estimate received pilot power
|
||||
q->pilot_power = srslte_vec_avg_power_cf(q->pilot_recv_signal, nrefs_sf);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -56,17 +56,17 @@ uint32_t srslte_refsignal_cs_v(uint32_t port_id, uint32_t ref_symbol_idx)
|
|||
}
|
||||
break;
|
||||
case 2:
|
||||
if (ref_symbol_idx < 2) {
|
||||
if (ref_symbol_idx == 0) {
|
||||
v = 0;
|
||||
} else {
|
||||
v = 3;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (ref_symbol_idx < 2) {
|
||||
if (ref_symbol_idx == 0) {
|
||||
v = 3;
|
||||
} else {
|
||||
v = 6;
|
||||
v = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -120,6 +120,7 @@ inline uint32_t srslte_refsignal_cs_nsymbol(uint32_t l, srslte_cp_t cp, uint32_t
|
|||
return 1+l*SRSLTE_CP_NSYMB(cp);
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32_t srslte_refsignal_mbsfn_nsymbol(uint32_t l)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
|
@ -176,22 +177,21 @@ free_and_exit:
|
|||
}
|
||||
|
||||
|
||||
int srslte_refsignal_mbsfn_init(srslte_refsignal_t * q, srslte_cell_t cell, uint16_t mbsfn_area_id)
|
||||
int srslte_refsignal_mbsfn_init(srslte_refsignal_t * q, uint32_t max_prb)
|
||||
{
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
uint32_t i, p;
|
||||
if (q != NULL &&
|
||||
srslte_cell_isvalid(&cell))
|
||||
if (q != NULL)
|
||||
{
|
||||
ret = SRSLTE_ERROR;
|
||||
bzero(q, sizeof(srslte_refsignal_t));
|
||||
q->cell = cell;
|
||||
|
||||
q->type = SRSLTE_SF_MBSFN;
|
||||
q->mbsfn_area_id = mbsfn_area_id;
|
||||
|
||||
|
||||
for (p=0;p<2;p++) {
|
||||
for (i=0;i<SRSLTE_NSUBFRAMES_X_FRAME;i++) {
|
||||
q->pilots[p][i] = srslte_vec_malloc(sizeof(cf_t) * q->cell.nof_prb * 18);
|
||||
q->pilots[p][i] = srslte_vec_malloc(sizeof(cf_t) * max_prb * 18);
|
||||
if (!q->pilots[p][i]) {
|
||||
perror("malloc");
|
||||
goto free_and_exit;
|
||||
|
@ -199,9 +199,7 @@ int srslte_refsignal_mbsfn_init(srslte_refsignal_t * q, srslte_cell_t cell, uint
|
|||
}
|
||||
}
|
||||
|
||||
if(srslte_refsignal_mbsfn_gen_seq(q, q->cell, q->mbsfn_area_id)) {
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -212,7 +210,24 @@ free_and_exit:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int srslte_refsignal_mbsfn_set_cell(srslte_refsignal_t * q, srslte_cell_t cell, uint16_t mbsfn_area_id){
|
||||
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
q->cell = cell;
|
||||
|
||||
q->mbsfn_area_id = mbsfn_area_id;
|
||||
if(srslte_refsignal_mbsfn_gen_seq(q, q->cell, q->mbsfn_area_id)) {
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
|
||||
free_and_exit:
|
||||
if (ret == SRSLTE_ERROR) {
|
||||
srslte_refsignal_free(q);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** Allocates memory for the 20 slots in a subframe
|
||||
|
@ -399,7 +414,7 @@ int srslte_refsignal_cs_get_sf(srslte_cell_t cell, uint32_t port_id, cf_t *sf_sy
|
|||
for (l=0;l<srslte_refsignal_cs_nof_symbols(port_id);l++) {
|
||||
uint32_t nsymbol = srslte_refsignal_cs_nsymbol(l, cell.cp, port_id);
|
||||
/* Compute offset frequency index */
|
||||
fidx = ((srslte_refsignal_cs_v(port_id, l) + (cell.id % 6)) % 6);
|
||||
fidx = srslte_refsignal_cs_fidx(cell, l, port_id, 0);
|
||||
for (i = 0; i < 2*cell.nof_prb; i++) {
|
||||
pilots[SRSLTE_REFSIGNAL_PILOT_IDX(i,l,cell)] = sf_symbols[SRSLTE_RE_IDX(cell.nof_prb, nsymbol, fidx)];
|
||||
fidx += SRSLTE_NRE/2; // 2 references per PRB
|
||||
|
|
|
@ -37,7 +37,9 @@ srslte_cell_t cell = {
|
|||
6, // nof_prb
|
||||
1, // nof_ports
|
||||
1000, // cell_id
|
||||
SRSLTE_CP_NORM // cyclic prefix
|
||||
SRSLTE_CP_NORM, // cyclic prefix
|
||||
SRSLTE_PHICH_NORM,
|
||||
SRSLTE_PHICH_R_1_6
|
||||
};
|
||||
|
||||
char *output_matlab = NULL;
|
||||
|
|
|
@ -37,7 +37,8 @@ srslte_cell_t cell = {
|
|||
1, // nof_ports
|
||||
0,
|
||||
1000, // cell_id
|
||||
SRSLTE_CP_NORM // cyclic prefix
|
||||
SRSLTE_CP_NORM, // cyclic prefix
|
||||
SRSLTE_PHICH_NORM
|
||||
};
|
||||
|
||||
char *output_matlab = NULL;
|
||||
|
@ -116,6 +117,7 @@ int main(int argc, char **argv) {
|
|||
perror("srslte_vec_malloc");
|
||||
goto do_exit;
|
||||
}
|
||||
bzero(ce, num_re*sizeof(cf_t));
|
||||
|
||||
if (cell.id == 1000) {
|
||||
cid = 0;
|
||||
|
|
|
@ -36,7 +36,9 @@ srslte_cell_t cell = {
|
|||
100, // nof_prb
|
||||
SRSLTE_MAX_PORTS, // nof_ports
|
||||
1, // cell_id
|
||||
SRSLTE_CP_NORM // cyclic prefix
|
||||
SRSLTE_CP_NORM, // cyclic prefix
|
||||
SRSLTE_PHICH_NORM,
|
||||
SRSLTE_PHICH_R_1_6
|
||||
};
|
||||
|
||||
void usage(char *prog) {
|
||||
|
|
|
@ -66,7 +66,7 @@ int srslte_timestamp_sub(srslte_timestamp_t *t, time_t full_secs, double frac_se
|
|||
t->frac_secs -= frac_secs;
|
||||
t->full_secs -= full_secs;
|
||||
if(t->frac_secs < 0){
|
||||
t->frac_secs = 1-t->frac_secs;
|
||||
t->frac_secs = t->frac_secs + 1;
|
||||
t->full_secs--;
|
||||
}
|
||||
if(t->full_secs < 0)
|
||||
|
|
|
@ -149,6 +149,7 @@ int srslte_ofdm_replan_(srslte_ofdm_t *q, srslte_cp_t cp, int symbol_sz, int nof
|
|||
|
||||
q->symbol_sz = (uint32_t) symbol_sz;
|
||||
q->nof_symbols = SRSLTE_CP_NSYMB(cp);
|
||||
q->nof_symbols_mbsfn = SRSLTE_CP_NSYMB(SRSLTE_CP_EXT);
|
||||
q->cp = cp;
|
||||
q->nof_re = (uint32_t) nof_prb * SRSLTE_NRE;
|
||||
q->nof_guards = ((symbol_sz - q->nof_re) / 2);
|
||||
|
@ -246,14 +247,15 @@ int srslte_ofdm_rx_init(srslte_ofdm_t *q, srslte_cp_t cp, cf_t *in_buffer, cf_t
|
|||
return srslte_ofdm_init_(q, cp, in_buffer, out_buffer, symbol_sz, max_prb, SRSLTE_DFT_FORWARD);
|
||||
}
|
||||
|
||||
int srslte_ofdm_rx_init_mbsfn(srslte_ofdm_t *q, srslte_cp_t cp, cf_t *in_buffer, cf_t *out_buffer, uint32_t nof_prb)
|
||||
int srslte_ofdm_rx_init_mbsfn(srslte_ofdm_t *q, srslte_cp_t cp, cf_t *in_buffer, cf_t *out_buffer, uint32_t max_prb)
|
||||
{
|
||||
int symbol_sz = srslte_symbol_sz(nof_prb);
|
||||
int symbol_sz = srslte_symbol_sz(max_prb);
|
||||
if (symbol_sz < 0) {
|
||||
fprintf(stderr, "Error: Invalid nof_prb=%d\n", nof_prb);
|
||||
fprintf(stderr, "Error: Invalid nof_prb=%d\n", max_prb);
|
||||
return -1;
|
||||
}
|
||||
return srslte_ofdm_init_mbsfn_(q, cp, in_buffer, out_buffer, symbol_sz, nof_prb, SRSLTE_DFT_FORWARD, SRSLTE_SF_MBSFN);
|
||||
q->max_prb = max_prb;
|
||||
return srslte_ofdm_init_mbsfn_(q, cp, in_buffer, out_buffer, symbol_sz, max_prb, SRSLTE_DFT_FORWARD, SRSLTE_SF_MBSFN);
|
||||
}
|
||||
|
||||
|
||||
|
@ -292,7 +294,7 @@ int srslte_ofdm_tx_init_mbsfn(srslte_ofdm_t *q, srslte_cp_t cp, cf_t *in_buffer,
|
|||
fprintf(stderr, "Error: Invalid nof_prb=%d\n", nof_prb);
|
||||
return -1;
|
||||
}
|
||||
|
||||
q->max_prb = nof_prb;
|
||||
ret = srslte_ofdm_init_mbsfn_(q, cp, in_buffer, out_buffer, symbol_sz, nof_prb, SRSLTE_DFT_BACKWARD, SRSLTE_SF_MBSFN);
|
||||
|
||||
if (ret == SRSLTE_SUCCESS) {
|
||||
|
@ -559,7 +561,6 @@ void srslte_ofdm_tx_slot(srslte_ofdm_t *q, int slot_in_sf) {
|
|||
void srslte_ofdm_tx_slot_mbsfn(srslte_ofdm_t *q, cf_t *input, cf_t *output)
|
||||
{
|
||||
uint32_t i, cp_len;
|
||||
|
||||
for(i=0;i<q->nof_symbols_mbsfn;i++) {
|
||||
cp_len = ( i>(q->non_mbsfn_region-1) )?SRSLTE_CP_LEN_EXT(q->symbol_sz):SRSLTE_CP_LEN_NORM(i, q->symbol_sz);
|
||||
memcpy(&q->tmp[q->nof_guards], input, q->nof_re * sizeof(cf_t));
|
||||
|
|
|
@ -69,6 +69,13 @@ int srslte_enb_dl_init(srslte_enb_dl_t *q, cf_t *out_buffer[SRSLTE_MAX_PORTS], u
|
|||
goto clean_exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (srslte_ofdm_tx_init_mbsfn(&q->ifft_mbsfn, SRSLTE_CP_EXT, q->sf_symbols[0], out_buffer[0], max_prb)) {
|
||||
fprintf(stderr, "Error initiating FFT \n");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
|
||||
if (srslte_pbch_init(&q->pbch)) {
|
||||
fprintf(stderr, "Error creating PBCH object\n");
|
||||
|
@ -82,7 +89,15 @@ int srslte_enb_dl_init(srslte_enb_dl_t *q, cf_t *out_buffer[SRSLTE_MAX_PORTS], u
|
|||
fprintf(stderr, "Error creating PHICH object\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
int mbsfn_area_id = 1;
|
||||
|
||||
|
||||
if (srslte_pmch_init(&q->pmch, max_prb)) {
|
||||
fprintf(stderr, "Error creating PMCH object\n");
|
||||
}
|
||||
srslte_pmch_set_area_id(&q->pmch, mbsfn_area_id);
|
||||
|
||||
|
||||
if (srslte_pdcch_init_enb(&q->pdcch, max_prb)) {
|
||||
fprintf(stderr, "Error creating PDCCH object\n");
|
||||
goto clean_exit;
|
||||
|
@ -97,7 +112,11 @@ int srslte_enb_dl_init(srslte_enb_dl_t *q, cf_t *out_buffer[SRSLTE_MAX_PORTS], u
|
|||
fprintf(stderr, "Error initializing CSR signal (%d)\n",ret);
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
|
||||
if (srslte_refsignal_mbsfn_init(&q->mbsfnr_signal, max_prb)) {
|
||||
fprintf(stderr, "Error initializing CSR signal (%d)\n",ret);
|
||||
goto clean_exit;
|
||||
}
|
||||
ret = SRSLTE_SUCCESS;
|
||||
|
||||
} else {
|
||||
|
@ -117,15 +136,16 @@ void srslte_enb_dl_free(srslte_enb_dl_t *q)
|
|||
for (int i = 0; i < SRSLTE_MAX_PORTS; i++) {
|
||||
srslte_ofdm_tx_free(&q->ifft[i]);
|
||||
}
|
||||
srslte_ofdm_tx_free(&q->ifft_mbsfn);
|
||||
srslte_regs_free(&q->regs);
|
||||
srslte_pbch_free(&q->pbch);
|
||||
srslte_pcfich_free(&q->pcfich);
|
||||
srslte_phich_free(&q->phich);
|
||||
srslte_pdcch_free(&q->pdcch);
|
||||
srslte_pdsch_free(&q->pdsch);
|
||||
|
||||
srslte_pmch_free(&q->pmch);
|
||||
srslte_refsignal_free(&q->csr_signal);
|
||||
|
||||
srslte_refsignal_free(&q->mbsfnr_signal);
|
||||
for (int i=0;i<SRSLTE_MAX_PORTS;i++) {
|
||||
if (q->sf_symbols[i]) {
|
||||
free(q->sf_symbols[i]);
|
||||
|
@ -159,6 +179,15 @@ int srslte_enb_dl_set_cell(srslte_enb_dl_t *q, srslte_cell_t cell)
|
|||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (srslte_ofdm_tx_set_prb(&q->ifft_mbsfn, SRSLTE_CP_EXT, q->cell.nof_prb)) {
|
||||
fprintf(stderr, "Error re-planning ifft_mbsfn\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
srslte_ofdm_set_non_mbsfn_region(&q->ifft_mbsfn, 2);
|
||||
//srslte_ofdm_set_normalize(&q->ifft_mbsfn, true);
|
||||
|
||||
if (srslte_pbch_set_cell(&q->pbch, q->cell)) {
|
||||
fprintf(stderr, "Error creating PBCH object\n");
|
||||
return SRSLTE_ERROR;
|
||||
|
@ -181,11 +210,21 @@ int srslte_enb_dl_set_cell(srslte_enb_dl_t *q, srslte_cell_t cell)
|
|||
fprintf(stderr, "Error creating PDSCH object\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
if (srslte_pmch_set_cell(&q->pmch, q->cell)) {
|
||||
fprintf(stderr, "Error creating PMCH object\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
if (srslte_refsignal_cs_set_cell(&q->csr_signal, q->cell)) {
|
||||
fprintf(stderr, "Error initializing CSR signal (%d)\n",ret);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
int mbsfn_area_id = 1;
|
||||
if (srslte_refsignal_mbsfn_set_cell(&q->mbsfnr_signal, q->cell, mbsfn_area_id)) {
|
||||
fprintf(stderr, "Error initializing MBSFNR signal (%d)\n",ret);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
/* Generate PSS/SSS signals */
|
||||
srslte_pss_generate(q->pss_signal, cell.id%3);
|
||||
srslte_sss_generate(q->sss_signal0, q->sss_signal5, cell.id);
|
||||
|
@ -201,6 +240,11 @@ int srslte_enb_dl_set_cell(srslte_enb_dl_t *q, srslte_cell_t cell)
|
|||
|
||||
|
||||
|
||||
void srslte_enb_dl_set_non_mbsfn_region(srslte_enb_dl_t *q, uint8_t non_mbsfn_region)
|
||||
{
|
||||
srslte_ofdm_set_non_mbsfn_region(&q->ifft_mbsfn, non_mbsfn_region);
|
||||
}
|
||||
|
||||
void srslte_enb_dl_set_amp(srslte_enb_dl_t *q, float amp)
|
||||
{
|
||||
q->tx_amp = amp;
|
||||
|
@ -334,17 +378,30 @@ void srslte_enb_dl_put_base(srslte_enb_dl_t *q, uint32_t tti)
|
|||
|
||||
}
|
||||
|
||||
void srslte_enb_dl_put_mbsfn_base(srslte_enb_dl_t *q, uint32_t tti)
|
||||
{
|
||||
uint32_t sf_idx1 = tti%10;
|
||||
srslte_enb_dl_put_pcfich(q, sf_idx1);
|
||||
srslte_refsignal_mbsfn_put_sf(q->cell, 0,q->csr_signal.pilots[0][sf_idx1], q->mbsfnr_signal.pilots[0][sf_idx1], q->sf_symbols[0]);
|
||||
}
|
||||
|
||||
void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q)
|
||||
{
|
||||
// TODO: PAPR control
|
||||
float norm_factor = (float) sqrt(q->cell.nof_prb)/15/sqrt(q->ifft[0].symbol_sz);
|
||||
|
||||
for (int i = 0; i < q->cell.nof_ports; i++) {
|
||||
srslte_ofdm_tx_sf(&q->ifft[i]);
|
||||
srslte_vec_sc_prod_cfc(q->ifft[i].out_buffer, q->tx_amp*norm_factor, q->ifft[i].out_buffer, (uint32_t) SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
|
||||
srslte_ofdm_tx_sf(&q->ifft[i]);
|
||||
srslte_vec_sc_prod_cfc(q->ifft[i].out_buffer, norm_factor, q->ifft[i].out_buffer, (uint32_t) SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
|
||||
}
|
||||
}
|
||||
|
||||
void srslte_enb_dl_gen_signal_mbsfn(srslte_enb_dl_t *q)
|
||||
{
|
||||
float norm_factor = (float) sqrt(q->cell.nof_prb)/15/sqrt(q->ifft_mbsfn.symbol_sz);
|
||||
srslte_ofdm_tx_sf(&q->ifft_mbsfn);
|
||||
srslte_vec_sc_prod_cfc(q->ifft_mbsfn.out_buffer, norm_factor, q->ifft_mbsfn.out_buffer, (uint32_t) SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
|
||||
}
|
||||
|
||||
int srslte_enb_dl_add_rnti(srslte_enb_dl_t *q, uint16_t rnti)
|
||||
{
|
||||
return srslte_pdsch_set_rnti(&q->pdsch, rnti);
|
||||
|
@ -438,7 +495,23 @@ int srslte_enb_dl_put_pdsch(srslte_enb_dl_t *q, srslte_ra_dl_grant_t *grant, srs
|
|||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int srslte_enb_dl_put_pmch(srslte_enb_dl_t *q, srslte_ra_dl_grant_t *grant, srslte_softbuffer_tx_t *softbuffer, uint32_t sf_idx, uint8_t *data_mbms)
|
||||
{
|
||||
/* Encode PMCH */
|
||||
|
||||
int mbsfn_area_id = 1;
|
||||
if (srslte_pmch_cfg(&q->pmch_cfg, q->cell, grant, q->cfi, sf_idx)) {
|
||||
fprintf(stderr, "Error configuring PMCH\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
/* Encode PMCH */
|
||||
if (srslte_pmch_encode(&q->pmch, &q->pmch_cfg, softbuffer, data_mbms, mbsfn_area_id, q->sf_symbols)) {
|
||||
fprintf(stderr, "Error encoding PDSCH\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
void srslte_enb_dl_save_signal(srslte_enb_dl_t *q, srslte_softbuffer_tx_t *softbuffer, uint8_t *data, uint32_t tti, uint32_t rv_idx, uint16_t rnti, uint32_t cfi)
|
||||
{
|
||||
|
|
|
@ -40,7 +40,7 @@ uint32_t long_cb = 0;
|
|||
|
||||
void usage(char *prog) {
|
||||
printf("Usage: %s\n", prog);
|
||||
printf("\t-l long_cb [Default check all]\n", long_cb);
|
||||
printf("\t-l long_cb [Default %u]\n", long_cb);
|
||||
}
|
||||
|
||||
void parse_args(int argc, char **argv) {
|
||||
|
|
|
@ -244,6 +244,7 @@ int main(int argc, char **argv) {
|
|||
for (j=0;j<coded_length;j++) {
|
||||
llr_s[j] = (int16_t) (100*llr[j]);
|
||||
}
|
||||
|
||||
/* decoder */
|
||||
srslte_tdec_reset(&tdec, frame_length);
|
||||
|
||||
|
@ -259,11 +260,12 @@ int main(int argc, char **argv) {
|
|||
|
||||
for (int n=0;n<SRSLTE_TDEC_MAX_NPAR;n++) {
|
||||
if (n < nof_cb) {
|
||||
input[n] = llr_s;
|
||||
input[n] = llr_s;
|
||||
output[n] = data_rx_bytes[n];
|
||||
} else {
|
||||
input[n] = NULL;
|
||||
input[n] = NULL;
|
||||
output[n] = NULL;
|
||||
}
|
||||
output[n] = data_rx_bytes[n];
|
||||
}
|
||||
|
||||
gettimeofday(&tdata[1], NULL);
|
||||
|
@ -297,13 +299,18 @@ int main(int argc, char **argv) {
|
|||
if (errors) {
|
||||
printf("%d Errors\n", errors/nof_cb);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int cb=0;cb<SRSLTE_TDEC_MAX_NPAR;cb++) {
|
||||
if (data_rx_bytes[cb]) {
|
||||
free(data_rx_bytes[cb]);
|
||||
}
|
||||
}
|
||||
free(data_tx);
|
||||
free(symbols);
|
||||
free(llr);
|
||||
free(llr_c);
|
||||
free(llr_s);
|
||||
free(data_rx);
|
||||
|
||||
srslte_tdec_free(&tdec);
|
||||
|
|
|
@ -278,6 +278,7 @@ int main(int argc, char **argv) {
|
|||
free(symbols);
|
||||
free(llr);
|
||||
free(llr_c);
|
||||
free(llr_s);
|
||||
free(data_rx);
|
||||
free(data_rx2);
|
||||
|
||||
|
|
|
@ -513,7 +513,9 @@ void srslte_tdec_simd_decision_byte_cb(srslte_tdec_simd_t * h, uint8_t *output,
|
|||
void srslte_tdec_simd_decision_byte(srslte_tdec_simd_t * h, uint8_t *output[SRSLTE_TDEC_MAX_NPAR], uint32_t long_cb)
|
||||
{
|
||||
for (int i=0;i<h->max_par_cb;i++) {
|
||||
srslte_tdec_simd_decision_byte_cb(h, output[i], i, long_cb);
|
||||
if (output[i]) {
|
||||
srslte_tdec_simd_decision_byte_cb(h, output[i], i, long_cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ int srslte_layermap_multiplex(cf_t *d[SRSLTE_MAX_CODEWORDS], cf_t *x[SRSLTE_MAX_
|
|||
int nof_symbols[SRSLTE_MAX_CODEWORDS]) {
|
||||
if (nof_cw == nof_layers) {
|
||||
for (int i = 0; i < nof_cw; i++) {
|
||||
srs_vec_cf_cpy(x[i], d[i], (uint32_t) nof_symbols[0]);
|
||||
srs_vec_cf_cpy(d[i], x[i], (uint32_t) nof_symbols[0]);
|
||||
}
|
||||
return nof_symbols[0];
|
||||
} else if (nof_cw == 1) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -333,5 +333,11 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < nof_tx_ports; i++) {
|
||||
if (y[i]) {
|
||||
free(y[i]);
|
||||
}
|
||||
}
|
||||
|
||||
exit(ret);
|
||||
}
|
||||
|
|
|
@ -73,7 +73,9 @@ int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg, uint16_t msg_rnti,
|
|||
}
|
||||
|
||||
if (!dl_dci->is_ra_order) {
|
||||
srslte_ra_dl_dci_to_grant(dl_dci, nof_prb, msg_rnti, grant);
|
||||
if (srslte_ra_dl_dci_to_grant(dl_dci, nof_prb, msg_rnti, grant)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (SRSLTE_VERBOSE_ISINFO()) {
|
||||
srslte_ra_pdsch_fprint(stdout, dl_dci, nof_prb);
|
||||
|
@ -379,7 +381,7 @@ uint32_t srslte_dci_dl_info(char *info_str, uint32_t len, srslte_ra_dl_dci_t *dc
|
|||
dci_msg->type2_alloc.riv,
|
||||
dci_msg->type2_alloc.RB_start, dci_msg->type2_alloc.RB_start+dci_msg->type2_alloc.L_crb-1,
|
||||
dci_msg->type2_alloc.mode==SRSLTE_RA_TYPE2_LOC?"local":"dist");
|
||||
if (dci_msg->type2_alloc.mode==SRSLTE_RA_TYPE2_LOC) {
|
||||
if (dci_msg->type2_alloc.mode==SRSLTE_RA_TYPE2_DIST) {
|
||||
n += snprintf(&info_str[n], len-n, ", ngap=%s, nprb1a=%d",
|
||||
dci_msg->type2_alloc.n_gap==SRSLTE_RA_TYPE2_NG1?"ng1":"ng2",
|
||||
dci_msg->type2_alloc.n_prb1a==SRSLTE_RA_TYPE2_NPRB1A_2?2:3);
|
||||
|
|
|
@ -221,7 +221,7 @@ int srslte_pcfich_decode_multi(srslte_pcfich_t *q, cf_t *sf_symbols[SRSLTE_MAX_P
|
|||
/* no need for layer demapping */
|
||||
srslte_predecoding_single_multi(q_symbols, q_ce[0], q->d, NULL, q->nof_rx_antennas, q->nof_symbols, 1.0f, noise_estimate);
|
||||
} else {
|
||||
srslte_predecoding_diversity_multi(q_symbols, q_ce, x, q->nof_rx_antennas, q->cell.nof_ports, q->nof_symbols, 1.0f);
|
||||
srslte_predecoding_diversity_multi(q_symbols, q_ce, x, NULL, q->nof_rx_antennas, q->cell.nof_ports, q->nof_symbols, 1.0f);
|
||||
srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports, q->nof_symbols / q->cell.nof_ports);
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue