Merge branch 'next' into neon_windowed_tdec

master
Ismael Gomez 6 years ago
commit 8f541cf4e1

@ -0,0 +1,115 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: true #Changed
AlignConsecutiveDeclarations: true #Changed
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline #Changed
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true #Changed
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: true #Changed
AfterControlStatement: false
AfterEnum: false
AfterFunction: true #Changed
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom #Changed
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: AfterColon #Changed
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 120 #Changed
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true #Changed
ConstructorInitializerIndentWidth: 2 #Changed
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: true #Changed
IndentPPDirectives: None
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left #Changed
RawStringFormats:
- Delimiter: pb
Language: TextProto
BasedOnStyle: google
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp03 #Changed
TabWidth: 8
UseTab: Never
...

@ -317,7 +317,8 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
endif(NOT ${CMAKE_BUILD_TYPE} STREQUAL "Debug")
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon -march=native -DIS_ARM -DHAVE_NEON")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon -march=native -DIS_ARM -DHAVE_NEON")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DIS_ARM")
message(STATUS "have ARM")
set(HAVE_NEON "True")
else(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")

@ -3,8 +3,29 @@
# 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"
# check if install mode has been provided
if ([ ! $1 ])
then
echo "Please call script with either user or service as first parameter."
echo ""
echo "E.g. ./srslte_install_configs.sh user"
echo " .. to install all config files to $HOME/.srs"
echo ""
echo "E.g. ./srslte_install_configs.sh service"
echo " .. to install all config files to /etc/srslte"
exit
fi
if [ "$1" == "user" ]
then
dest_folder="$HOME/.srs"
elif [ "$1" == "service" ]
then
dest_folder="/etc/srslte"
else
echo "Please call script with either user or service as first parameter."
exit
fi
install_file(){
source_path="$SRSLTE_INSTALL_DIR/$1"
@ -40,6 +61,9 @@ echo "Installing srsLTE configuration files:"
if [ ! -d "$dest_folder" ]; then
echo " - Creating srsLTE config folder $dest_folder"
mkdir $dest_folder
if [ $? -ne 0 ]; then
exit
fi
fi

@ -35,22 +35,32 @@ 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;
// try to find file in /etc/srslte
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());
snprintf(full_path, sizeof(full_path), "/etc/srslte/%s", default_name.c_str());
filename = std::string(full_path);
// try to open again
conf.open(filename.c_str());
if (conf.fail()) {
return false;
// try home folder
const char* homedir = NULL;
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;

@ -70,12 +70,14 @@ public:
class srslte_pdcp_config_t
{
public:
srslte_pdcp_config_t(bool is_control_ = false, bool is_data_ = false, uint8_t direction_ = SECURITY_DIRECTION_UPLINK)
:direction(direction_)
srslte_pdcp_config_t(uint8_t bearer_id_ = 0, bool is_control_ = false, bool is_data_ = false, uint8_t direction_ = SECURITY_DIRECTION_UPLINK)
:bearer_id(bearer_id_)
,direction(direction_)
,is_control(is_control_)
,is_data(is_data_)
,sn_len(12) {}
uint32_t bearer_id;
uint8_t direction;
bool is_control;
bool is_data;

@ -194,7 +194,7 @@ public:
const static int MAX_FOUND_PLMNS = 16;
virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
virtual void write_sdu(srslte::byte_buffer_t *sdu) = 0;
virtual uint16_t get_mcc() = 0;
virtual uint16_t get_mnc() = 0;
virtual void enable_capabilities() = 0;
@ -300,11 +300,12 @@ public:
class rlc_interface_mac : public srslte::read_pdu_interface
{
public:
/* MAC calls RLC to get buffer state for a logical channel.
* This function should return quickly. */
virtual uint32_t get_buffer_state(uint32_t lcid) = 0;
virtual uint32_t get_total_buffer_state(uint32_t lcid) = 0;
/* MAC calls has_data() to query whether a logical channel has data to transmit (without
* knowing how much. This function should return quickly. */
virtual bool has_data(const uint32_t lcid) = 0;
/* MAC calls RLC to get the buffer state for a logical channel. */
virtual uint32_t get_buffer_state(const uint32_t lcid) = 0;
const static int MAX_PDU_SEGMENTS = 20;

@ -129,8 +129,6 @@ private:
uint32_t count,
uint32_t ct_len,
uint8_t *msg);
uint8_t get_bearer_id(uint8_t lcid);
};
/****************************************************************************

@ -67,8 +67,8 @@ public:
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);
bool has_data(const uint32_t lcid);
uint32_t get_buffer_state(const 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);

@ -89,8 +89,8 @@ public:
void write_sdu(byte_buffer_t *sdu, bool blocking = true);
// MAC interface
bool has_data();
uint32_t get_buffer_state();
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);
@ -117,8 +117,8 @@ private:
void write_sdu(byte_buffer_t *sdu, bool blocking);
int read_pdu(uint8_t *payload, uint32_t nof_bytes);
bool has_data();
uint32_t get_buffer_state();
uint32_t get_total_buffer_state();
uint32_t get_num_tx_bytes();
void reset_metrics();

@ -169,8 +169,8 @@ public:
virtual void write_sdu(byte_buffer_t *sdu, bool blocking) = 0;
// MAC interface
virtual bool has_data() = 0;
virtual uint32_t get_buffer_state() = 0;
virtual uint32_t get_total_buffer_state() = 0;
virtual int read_pdu(uint8_t *payload, uint32_t nof_bytes) = 0;
virtual void write_pdu(uint8_t *payload, uint32_t nof_bytes) = 0;
};

@ -62,8 +62,8 @@ public:
void write_sdu(byte_buffer_t *sdu, bool blocking);
// MAC interface
bool has_data();
uint32_t get_buffer_state();
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);

@ -110,8 +110,11 @@ public:
unread_bytes = 0;
}
bool is_empty() {
return queue.empty();
}
private:
bool is_empty() { return queue.empty(); }
block_queue<byte_buffer_t*> queue;
uint32_t unread_bytes;

@ -68,8 +68,8 @@ public:
void write_sdu(byte_buffer_t *sdu, bool blocking = true);
// MAC interface
bool has_data();
uint32_t get_buffer_state();
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();
@ -96,7 +96,8 @@ private:
void try_write_sdu(byte_buffer_t *sdu);
uint32_t get_num_tx_bytes();
void reset_metrics();
uint32_t get_buffer_size_bytes();
bool has_data();
uint32_t get_buffer_state();
private:
byte_buffer_pool *pool;

@ -320,7 +320,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_mobile_id_ie(LIBLTE_MME_MOBILE_ID_STRUCT *mob
odd = false;
}else if(LIBLTE_MME_MOBILE_ID_TYPE_TMSI == mobile_id->type_of_id){
id32 = mobile_id->tmsi;
length = 4;
length = 5;
odd = false;
}
}else{

@ -25,6 +25,8 @@ add_library(srslte_common STATIC ${C_SOURCES} ${CXX_SOURCES})
add_custom_target(gen_build_info COMMAND cmake -P ${CMAKE_BINARY_DIR}/SRSLTEbuildinfo.cmake)
add_dependencies(srslte_common gen_build_info)
add_executable(arch_select arch_select.cc)
target_include_directories(srslte_common PUBLIC ${SEC_INCLUDE_DIRS})
target_link_libraries(srslte_common ${SEC_LIBRARIES})
install(TARGETS srslte_common DESTINATION ${LIBRARY_DIR})

@ -0,0 +1,116 @@
/**
*
* \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 <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef IS_ARM
#include <stdio.h>
#include <sys/auxv.h>
#include <asm/hwcap.h>
#else
#include <cpuid.h>
#define X86_CPUID_BASIC_LEAF 1
#define X86_CPUID_ADVANCED_LEAF 7
#endif
#define MAX_CMD_LEN (64)
#ifndef IS_ARM
static __inline int __get_cpuid_count_redef(unsigned int __leaf, unsigned int __subleaf, unsigned int* __eax,
unsigned int* __ebx, unsigned int* __ecx, unsigned int* __edx)
{
unsigned int __max_leaf = __get_cpuid_max(__leaf & 0x80000000, 0);
if (__max_leaf == 0 || __max_leaf < __leaf)
return 0;
__cpuid_count(__leaf, __subleaf, *__eax, *__ebx, *__ecx, *__edx);
return 1;
}
const char* x86_get_isa()
{
int ret = 0;
int has_sse42 = 0, has_avx = 0, has_avx2 = 0;
unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
// query basic features
ret = __get_cpuid(X86_CPUID_BASIC_LEAF, &eax, &ebx, &ecx, &edx);
if (ret) {
has_sse42 = ecx & bit_SSE4_2;
has_avx = ecx & bit_AVX;
}
// query advanced features
ret = __get_cpuid_count_redef(X86_CPUID_ADVANCED_LEAF, 0, &eax, &ebx, &ecx, &edx);
if (ret) {
has_avx2 = ebx & bit_AVX2;
}
if (has_avx2) {
return "avx2";
} else
if (has_avx) {
return "avx";
} else
if (has_sse42) {
return "sse4.2";
} else {
return "generic";
}
}
#endif
#ifdef IS_ARM
const char* arm_get_isa()
{
if (getauxval(AT_HWCAP) & HWCAP_NEON) {
return "neon";
} else {
return "generic";
}
}
#endif
int main(int argc, char *argv[])
{
char cmd[MAX_CMD_LEN];
#ifdef IS_ARM
snprintf(cmd, MAX_CMD_LEN, "%s-%s", argv[0], arm_get_isa());
#else
snprintf(cmd, MAX_CMD_LEN, "%s-%s", argv[0], x86_get_isa());
#endif
// execute command with same argument
if (execvp(cmd, &argv[0]) == -1) {
fprintf(stderr, "%s: %s\n", cmd, strerror(errno));
exit(errno);
}
}

@ -363,17 +363,23 @@ void radio::set_tx_srate(double srate)
double srate_khz = round(cur_tx_srate/1e3);
if (srate_khz == 1.92e3) {
nsamples = 54;
// 6 PRB
nsamples = 94;
} else if (srate_khz == 3.84e3) {
nsamples = 69;
// 15 PRB
nsamples = 94;
} else if (srate_khz == 5.76e3) {
nsamples = 93;
// 25 PRB
nsamples = 92;
} else if (srate_khz == 11.52e3) {
nsamples = 120;
// 50 PRB
nsamples = 171;
} else if (srate_khz == 15.36e3) {
nsamples = 131;
// 75 PRB
nsamples = 171;
} else if (srate_khz == 23.04e3) {
nsamples = 150;
// 100 PRB
nsamples = 171;
} else {
/* Interpolate from known values */
printf("\nWarning TX/RX time offset for sampling rate %.0f KHz not calibrated. Using interpolated value\n\n", cur_tx_srate);
@ -403,17 +409,17 @@ void radio::set_tx_srate(double srate)
} else if(!strcmp(srslte_rf_name(&rf_device), "lime")) {
double srate_khz = round(cur_tx_srate/1e3);
if (srate_khz == 1.92e3) {
nsamples = 70;// estimated
nsamples = 76;
} else if (srate_khz == 3.84e3) {
nsamples = 76;//estimated
nsamples = 76;
} else if (srate_khz == 5.76e3) {
nsamples = 76;
} else if (srate_khz == 11.52e3) {
nsamples = 76;
} else if (srate_khz == 15.36e3) {
nsamples = 73;
nsamples = 76;
} else if (srate_khz == 23.04e3) {
nsamples = 87;
nsamples = 76;
} else {
/* Interpolate from known values */
printf("\nWarning TX/RX time offset for sampling rate %.0f KHz not calibrated. Using interpolated value\n\n", cur_tx_srate);

@ -244,7 +244,7 @@ void pdcp_entity::integrity_generate( uint8_t *msg,
case INTEGRITY_ALGORITHM_ID_128_EIA1:
security_128_eia1(&k_int[16],
tx_count,
get_bearer_id(lcid),
cfg.bearer_id - 1,
cfg.direction,
msg,
msg_len,
@ -253,7 +253,7 @@ void pdcp_entity::integrity_generate( uint8_t *msg,
case INTEGRITY_ALGORITHM_ID_128_EIA2:
security_128_eia2(&k_int[16],
tx_count,
get_bearer_id(lcid),
cfg.bearer_id - 1,
cfg.direction,
msg,
msg_len,
@ -266,7 +266,7 @@ void pdcp_entity::integrity_generate( uint8_t *msg,
log->debug("Integrity gen input:\n");
log->debug_hex(&k_int[16], 16, " K_int");
log->debug(" Local count: %d\n", tx_count);
log->debug(" Bearer ID: %d\n", get_bearer_id(lcid));
log->debug(" Bearer ID: %d\n", cfg.bearer_id);
log->debug(" Direction: %s\n", (cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? "Downlink" : "Uplink");
log->debug_hex(msg, msg_len, " Message");
log->debug_hex(mac, 4, "MAC (generated)");
@ -288,7 +288,7 @@ bool pdcp_entity::integrity_verify(uint8_t *msg,
case INTEGRITY_ALGORITHM_ID_128_EIA1:
security_128_eia1(&k_int[16],
count,
get_bearer_id(lcid),
cfg.bearer_id - 1,
(cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK),
msg,
msg_len,
@ -297,7 +297,7 @@ bool pdcp_entity::integrity_verify(uint8_t *msg,
case INTEGRITY_ALGORITHM_ID_128_EIA2:
security_128_eia2(&k_int[16],
count,
get_bearer_id(lcid),
cfg.bearer_id - 1,
(cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK),
msg,
msg_len,
@ -310,7 +310,7 @@ bool pdcp_entity::integrity_verify(uint8_t *msg,
log->debug("Integrity check input:\n");
log->debug_hex(&k_int[16], 16, " K_int");
log->debug(" Local count: %d\n", count);
log->debug(" Bearer ID: %d\n", get_bearer_id(lcid));
log->debug(" Bearer ID: %d\n", cfg.bearer_id);
log->debug(" Direction: %s\n", (cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? "Uplink" : "Downlink");
log->debug_hex(msg, msg_len, " Message");
@ -351,7 +351,7 @@ void pdcp_entity::cipher_encrypt(uint8_t *msg,
case CIPHERING_ALGORITHM_ID_128_EEA1:
security_128_eea1(&(k_enc[16]),
tx_count,
get_bearer_id(lcid),
cfg.bearer_id - 1,
cfg.direction,
msg,
msg_len,
@ -361,7 +361,7 @@ void pdcp_entity::cipher_encrypt(uint8_t *msg,
case CIPHERING_ALGORITHM_ID_128_EEA2:
security_128_eea2(&(k_enc[16]),
tx_count,
get_bearer_id(lcid),
cfg.bearer_id - 1,
cfg.direction,
msg,
msg_len,
@ -386,7 +386,7 @@ void pdcp_entity::cipher_decrypt(uint8_t *ct,
case CIPHERING_ALGORITHM_ID_128_EEA1:
security_128_eea1(&(k_enc[16]),
count,
get_bearer_id(lcid),
cfg.bearer_id - 1,
(cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK),
ct,
ct_len,
@ -396,7 +396,7 @@ void pdcp_entity::cipher_decrypt(uint8_t *ct,
case CIPHERING_ALGORITHM_ID_128_EEA2:
security_128_eea2(&(k_enc[16]),
count,
get_bearer_id(lcid),
cfg.bearer_id - 1,
(cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK),
ct,
ct_len,
@ -409,17 +409,6 @@ void pdcp_entity::cipher_decrypt(uint8_t *ct,
}
uint8_t pdcp_entity::get_bearer_id(uint8_t lcid)
{
#define RB_ID_SRB2 2
if(lcid <= RB_ID_SRB2) {
return lcid - 1;
} else {
return lcid - RB_ID_SRB2 - 1;
}
}
uint32_t pdcp_entity::get_dl_count()
{
return rx_count;

@ -256,26 +256,26 @@ bool rlc::rb_is_um(uint32_t lcid)
/*******************************************************************************
MAC interface
*******************************************************************************/
uint32_t rlc::get_buffer_state(uint32_t lcid)
bool rlc::has_data(uint32_t lcid)
{
uint32_t ret = 0;
bool has_data = false;
pthread_rwlock_rdlock(&rwlock);
if (valid_lcid(lcid)) {
ret = rlc_array.at(lcid)->get_buffer_state();
has_data = rlc_array.at(lcid)->has_data();
}
pthread_rwlock_unlock(&rwlock);
return ret;
return has_data;
}
uint32_t rlc::get_total_buffer_state(uint32_t lcid)
uint32_t rlc::get_buffer_state(uint32_t lcid)
{
uint32_t ret = 0;
pthread_rwlock_rdlock(&rwlock);
if (valid_lcid(lcid)) {
ret = rlc_array.at(lcid)->get_total_buffer_state();
ret = rlc_array.at(lcid)->get_buffer_state();
}
pthread_rwlock_unlock(&rwlock);
@ -288,7 +288,7 @@ uint32_t rlc::get_total_mch_buffer_state(uint32_t lcid)
pthread_rwlock_rdlock(&rwlock);
if (valid_lcid_mrb(lcid)) {
ret = rlc_array_mrb.at(lcid)->get_total_buffer_state();
ret = rlc_array_mrb.at(lcid)->get_buffer_state();
}
pthread_rwlock_unlock(&rwlock);

@ -152,14 +152,14 @@ void rlc_am::write_sdu(byte_buffer_t *sdu, bool blocking)
* MAC interface
***************************************************************************/
uint32_t rlc_am::get_buffer_state()
bool rlc_am::has_data()
{
return tx.get_buffer_state();
return tx.has_data();
}
uint32_t rlc_am::get_total_buffer_state()
uint32_t rlc_am::get_buffer_state()
{
return tx.get_total_buffer_state();
return tx.get_buffer_state();
}
int rlc_am::read_pdu(uint8_t *payload, uint32_t nof_bytes)
@ -314,63 +314,16 @@ bool rlc_am::rlc_am_tx::do_status()
return parent->rx.get_do_status();
}
uint32_t rlc_am::rlc_am_tx::get_buffer_state()
// Function is supposed to return as fast as possible
bool rlc_am::rlc_am_tx::has_data()
{
pthread_mutex_lock(&mutex);
uint32_t n_bytes = 0;
uint32_t n_sdus = 0;
// Bytes needed for status report
if (do_status() && not status_prohibited) {
n_bytes = parent->rx.get_status_pdu_length();
log->debug("%s Buffer state - status report: %d bytes\n", RB_NAME, n_bytes);
goto unlock_and_return;
}
// Bytes needed for retx
if (not retx_queue.empty()) {
rlc_amd_retx_t retx = retx_queue.front();
log->debug("Buffer state - retx - SN: %d, Segment: %s, %d:%d\n", retx.sn, retx.is_segment ? "true" : "false", retx.so_start, retx.so_end);
if(tx_window.end() != tx_window.find(retx.sn)) {
int req_bytes = required_buffer_size(retx);
if (req_bytes < 0) {
log->error("In get_buffer_state(): Removing retx.sn=%d from queue\n", retx.sn);
retx_queue.pop_front();
goto unlock_and_return;
}
n_bytes = static_cast<uint32_t>(req_bytes);
log->debug("Buffer state - retx: %d bytes\n", n_bytes);
goto unlock_and_return;
}
}
// Bytes needed for tx SDUs
if (tx_window.size() < 1024) {
n_sdus = tx_sdu_queue.size();
n_bytes = tx_sdu_queue.size_bytes();
if (tx_sdu != NULL) {
n_sdus++;
n_bytes += tx_sdu->N_bytes;
}
}
// Room needed for header extensions? (integer rounding)
if (n_sdus > 1) {
n_bytes += ((n_sdus-1)*1.5)+0.5;
}
// Room needed for fixed header?
if (n_bytes > 0) {
n_bytes += 3;
log->debug("Buffer state - tx SDUs: %d bytes\n", n_bytes);
}
unlock_and_return:
pthread_mutex_unlock(&mutex);
return n_bytes;
return (((do_status() && not status_prohibited)) || // if we have a status PDU to transmit
(not retx_queue.empty()) || // if we have a retransmission
(tx_sdu != NULL) || // if we are currently transmitting a SDU
(not tx_sdu_queue.is_empty())); // or if there is a SDU queued up for transmission
}
uint32_t rlc_am::rlc_am_tx::get_total_buffer_state()
uint32_t rlc_am::rlc_am_tx::get_buffer_state()
{
pthread_mutex_lock(&mutex);
uint32_t n_bytes = 0;
@ -385,11 +338,11 @@ uint32_t rlc_am::rlc_am_tx::get_total_buffer_state()
// Bytes needed for retx
if(not retx_queue.empty()) {
rlc_amd_retx_t retx = retx_queue.front();
log->debug("Buffer state - retx - SN: %d, Segment: %s, %d:%d\n", retx.sn, retx.is_segment ? "true" : "false", retx.so_start, retx.so_end);
log->debug("%s Buffer state - retx - SN: %d, Segment: %s, %d:%d\n", RB_NAME, retx.sn, retx.is_segment ? "true" : "false", retx.so_start, retx.so_end);
if(tx_window.end() != tx_window.find(retx.sn)) {
int req_bytes = required_buffer_size(retx);
if (req_bytes < 0) {
log->error("In get_total_buffer_state(): Removing retx.sn=%d from queue\n", retx.sn);
log->error("In get_buffer_state(): Removing retx.sn=%d from queue\n", retx.sn);
retx_queue.pop_front();
} else {
n_bytes += req_bytes;
@ -413,10 +366,10 @@ uint32_t rlc_am::rlc_am_tx::get_total_buffer_state()
n_bytes += ((n_sdus-1)*1.5)+0.5;
}
// Room needed for fixed header?
if (n_bytes > 0) {
// Room needed for fixed header of data PDUs
if (n_bytes > 0 && n_sdus > 0) {
n_bytes += 3;
log->debug("Buffer state - tx SDUs: %d bytes\n", n_bytes);
log->debug("%s Total buffer state - %d SDUs (%d B)\n", RB_NAME, n_sdus, n_bytes);
}
pthread_mutex_unlock(&mutex);

@ -123,14 +123,14 @@ void rlc_tm::write_sdu(byte_buffer_t *sdu, bool blocking)
}
// MAC interface
uint32_t rlc_tm::get_buffer_state()
bool rlc_tm::has_data()
{
return ul_queue.size_bytes();
return not ul_queue.is_empty();
}
uint32_t rlc_tm::get_total_buffer_state()
uint32_t rlc_tm::get_buffer_state()
{
return get_buffer_state();
return ul_queue.size_bytes();
}
uint32_t rlc_tm::get_num_tx_bytes()

@ -162,14 +162,14 @@ void rlc_um::write_sdu(byte_buffer_t *sdu, bool blocking)
* MAC interface
***************************************************************************/
uint32_t rlc_um::get_buffer_state()
bool rlc_um::has_data()
{
return tx.get_buffer_size_bytes();
return tx.has_data();
}
uint32_t rlc_um::get_total_buffer_state()
uint32_t rlc_um::get_buffer_state()
{
return get_buffer_state();
return tx.get_buffer_state();
}
int rlc_um::read_pdu(uint8_t *payload, uint32_t nof_bytes)
@ -313,7 +313,13 @@ void rlc_um::rlc_um_tx::reset_metrics()
}
uint32_t rlc_um::rlc_um_tx::get_buffer_size_bytes()
bool rlc_um::rlc_um_tx::has_data()
{
return (tx_sdu != NULL || !tx_sdu_queue.is_empty());
}
uint32_t rlc_um::rlc_um_tx::get_buffer_state()
{
// Bytes needed for tx SDUs
uint32_t n_sdus = tx_sdu_queue.size();

@ -132,6 +132,56 @@ bool enb::init(all_args_t *args_)
gtpu_log.set_hex_limit(args->log.gtpu_hex_limit);
s1ap_log.set_hex_limit(args->log.s1ap_hex_limit);
// Parse config files
srslte_cell_t cell_cfg;
phy_cfg_t phy_cfg;
rrc_cfg_t rrc_cfg;
if (parse_cell_cfg(args, &cell_cfg)) {
fprintf(stderr, "Error parsing Cell configuration\n");
return false;
}
if (parse_sibs(args, &rrc_cfg, &phy_cfg)) {
fprintf(stderr, "Error parsing SIB configuration\n");
return false;
}
if (parse_rr(args, &rrc_cfg)) {
fprintf(stderr, "Error parsing Radio Resources configuration\n");
return false;
}
if (parse_drb(args, &rrc_cfg)) {
fprintf(stderr, "Error parsing DRB configuration\n");
return false;
}
uint32_t prach_freq_offset = rrc_cfg.sibs[1].sib.sib2.rr_config_common_sib.prach_cnfg.prach_cnfg_info.prach_freq_offset;
if(cell_cfg.nof_prb>10) {
if (prach_freq_offset + 6 > cell_cfg.nof_prb - SRSLTE_MAX(rrc_cfg.cqi_cfg.nof_prb, rrc_cfg.sr_cfg.nof_prb)) {
fprintf(stderr, "Invalid PRACH configuration: frequency offset=%d outside bandwidth limits\n", prach_freq_offset);
return false;
}
if (prach_freq_offset < SRSLTE_MAX(rrc_cfg.cqi_cfg.nof_prb, rrc_cfg.sr_cfg.nof_prb)) {
fprintf(stderr, "Invalid PRACH configuration: frequency offset=%d lower than CQI offset: %d or SR offset: %d\n",
prach_freq_offset, rrc_cfg.cqi_cfg.nof_prb, rrc_cfg.sr_cfg.nof_prb);
return false;
}
} else { // 6 PRB case
if (prach_freq_offset+6 > cell_cfg.nof_prb) {
fprintf(stderr, "Invalid PRACH configuration: frequency interval=(%d, %d) does not fit into the eNB PRBs=(0,%d)\n",
prach_freq_offset, prach_freq_offset+6, cell_cfg.nof_prb);
return false;
}
}
rrc_cfg.inactivity_timeout_ms = args->expert.rrc_inactivity_timer;
rrc_cfg.enable_mbsfn = args->expert.enable_mbsfn;
// Copy cell struct to rrc and phy
memcpy(&rrc_cfg.cell, &cell_cfg, sizeof(srslte_cell_t));
memcpy(&phy_cfg.cell, &cell_cfg, sizeof(srslte_cell_t));
// Set up pcap and trace
if(args->pcap.enable)
{
@ -194,55 +244,6 @@ bool enb::init(all_args_t *args_)
radio.register_error_handler(rf_msg);
srslte_cell_t cell_cfg;
phy_cfg_t phy_cfg;
rrc_cfg_t rrc_cfg;
if (parse_cell_cfg(args, &cell_cfg)) {
fprintf(stderr, "Error parsing Cell configuration\n");
return false;
}
if (parse_sibs(args, &rrc_cfg, &phy_cfg)) {
fprintf(stderr, "Error parsing SIB configuration\n");
return false;
}
if (parse_rr(args, &rrc_cfg)) {
fprintf(stderr, "Error parsing Radio Resources configuration\n");
return false;
}
if (parse_drb(args, &rrc_cfg)) {
fprintf(stderr, "Error parsing DRB configuration\n");
return false;
}
uint32_t prach_freq_offset = rrc_cfg.sibs[1].sib.sib2.rr_config_common_sib.prach_cnfg.prach_cnfg_info.prach_freq_offset;
if(cell_cfg.nof_prb>10) {
if (prach_freq_offset + 6 > cell_cfg.nof_prb - SRSLTE_MAX(rrc_cfg.cqi_cfg.nof_prb, rrc_cfg.sr_cfg.nof_prb)) {
fprintf(stderr, "Invalid PRACH configuration: frequency offset=%d outside bandwidth limits\n", prach_freq_offset);
return false;
}
if (prach_freq_offset < SRSLTE_MAX(rrc_cfg.cqi_cfg.nof_prb, rrc_cfg.sr_cfg.nof_prb)) {
fprintf(stderr, "Invalid PRACH configuration: frequency offset=%d lower than CQI offset: %d or SR offset: %d\n",
prach_freq_offset, rrc_cfg.cqi_cfg.nof_prb, rrc_cfg.sr_cfg.nof_prb);
return false;
}
} else { // 6 PRB case
if (prach_freq_offset+6 > cell_cfg.nof_prb) {
fprintf(stderr, "Invalid PRACH configuration: frequency interval=(%d, %d) does not fit into the eNB PRBs=(0,%d)\n",
prach_freq_offset, prach_freq_offset+6, cell_cfg.nof_prb);
return false;
}
}
rrc_cfg.inactivity_timeout_ms = args->expert.rrc_inactivity_timer;
rrc_cfg.enable_mbsfn = args->expert.enable_mbsfn;
// Copy cell struct to rrc and phy
memcpy(&rrc_cfg.cell, &cell_cfg, sizeof(srslte_cell_t));
memcpy(&phy_cfg.cell, &cell_cfg, sizeof(srslte_cell_t));
// Init all layers
phy.init(&args->expert.phy, &phy_cfg, &radio, &mac, phy_log);
mac.init(&args->expert.mac, &cell_cfg, &phy, &rlc, &rrc, &mac_log);

@ -330,7 +330,7 @@ void ue::allocate_sdu(srslte::sch_pdu *pdu, uint32_t lcid, uint32_t total_sdu_le
if (sdu_space > 0) {
int sdu_len = SRSLTE_MIN(total_sdu_len, (uint32_t) sdu_space);
int n=1;
while(sdu_len > 3 && n > 0) {
while(sdu_len >= 2 && n > 0) { // minimum size is a single RLC AM status PDU (2 Byte)
if (pdu->new_subh()) { // there is space for a new subheader
log_h->debug("SDU: set_sdu(), lcid=%d, sdu_len=%d, sdu_space=%d\n", lcid, sdu_len, sdu_space);
n = pdu->get()->set_sdu(lcid, sdu_len, this);

@ -142,7 +142,7 @@ int rlc::read_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_b
if(users.count(rnti)) {
if(rnti != SRSLTE_MRNTI) {
ret = users[rnti].rlc->read_pdu(lcid, payload, nof_bytes);
tx_queue = users[rnti].rlc->get_total_buffer_state(lcid);
tx_queue = users[rnti].rlc->get_buffer_state(lcid);
} else {
ret = users[rnti].rlc->read_pdu_mch(lcid, payload, nof_bytes);
tx_queue = users[rnti].rlc->get_total_mch_buffer_state(lcid);
@ -168,7 +168,7 @@ void rlc::write_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof
// In the eNodeB, there is no polling for buffer state from the scheduler, thus
// communicate buffer state every time a new PDU is written
uint32_t tx_queue = users[rnti].rlc->get_total_buffer_state(lcid);
uint32_t tx_queue = users[rnti].rlc->get_buffer_state(lcid);
uint32_t retx_queue = 0;
log_h->debug("Buffer state PDCP: rnti=0x%x, lcid=%d, tx_queue=%d\n", rnti, lcid, tx_queue);
mac->rlc_buffer_state(rnti, lcid, tx_queue, retx_queue);
@ -191,7 +191,7 @@ void rlc::write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* sdu)
if (users.count(rnti)) {
if(rnti != SRSLTE_MRNTI){
users[rnti].rlc->write_sdu(lcid, sdu, false);
tx_queue = users[rnti].rlc->get_total_buffer_state(lcid);
tx_queue = users[rnti].rlc->get_buffer_state(lcid);
}else {
users[rnti].rlc->write_sdu_mch(lcid, sdu);
tx_queue = users[rnti].rlc->get_total_mch_buffer_state(lcid);

@ -1450,6 +1450,7 @@ void rrc::ue::send_connection_setup(bool is_setup)
// Configure SRB1 in PDCP
srslte::srslte_pdcp_config_t pdcp_cnfg;
pdcp_cnfg.bearer_id = 1;
pdcp_cnfg.is_control = true;
pdcp_cnfg.direction = SECURITY_DIRECTION_DOWNLINK;
parent->pdcp->add_bearer(rnti, 1, pdcp_cnfg);
@ -1670,6 +1671,7 @@ void rrc::ue::send_connection_reconf(srslte::byte_buffer_t *pdu)
// Configure SRB2 in PDCP
srslte::srslte_pdcp_config_t pdcp_cnfg;
pdcp_cnfg.bearer_id = 2;
pdcp_cnfg.direction = SECURITY_DIRECTION_DOWNLINK;
pdcp_cnfg.is_control = true;
pdcp_cnfg.is_data = false;
@ -1753,7 +1755,11 @@ void rrc::ue::send_connection_reconf_new_bearer(LIBLTE_S1AP_E_RABTOBESETUPLISTBE
// Configure DRB in RLC
parent->rlc->add_bearer(rnti, lcid, &conn_reconf->rr_cnfg_ded.drb_to_add_mod_list[i].rlc_cnfg);
// Configure DRB in PDCP
parent->pdcp->add_bearer(rnti, lcid, &conn_reconf->rr_cnfg_ded.drb_to_add_mod_list[i].pdcp_cnfg);
srslte::srslte_pdcp_config_t pdcp_config;
pdcp_config.bearer_id = conn_reconf->rr_cnfg_ded.drb_to_add_mod_list[i].drb_id;
pdcp_config.is_data = true;
pdcp_config.direction = SECURITY_DIRECTION_DOWNLINK;
parent->pdcp->add_bearer(rnti, lcid, pdcp_config);
// DRB has already been configured in GTPU through bearer setup
// Add NAS message

@ -181,6 +181,7 @@ private:
void parse_esm_information_request(uint32_t lcid, byte_buffer_t *pdu);
void parse_emm_information(uint32_t lcid, byte_buffer_t *pdu);
void parse_detach_request(uint32_t lcid, byte_buffer_t *pdu);
void parse_emm_status(uint32_t lcid, byte_buffer_t *pdu);
// Packet generators
void gen_attach_request(byte_buffer_t *msg);

@ -290,7 +290,7 @@ public:
bool mbms_service_start(uint32_t serv, uint32_t port);
// NAS interface
void write_sdu(uint32_t lcid, byte_buffer_t *sdu);
void write_sdu(byte_buffer_t *sdu);
void enable_capabilities();
uint16_t get_mcc();
uint16_t get_mnc();
@ -603,7 +603,7 @@ private:
void send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause);
void send_con_restablish_complete();
void send_con_setup_complete(byte_buffer_t *nas_msg);
void send_ul_info_transfer(uint32_t lcid, byte_buffer_t *nas_msg);
void send_ul_info_transfer(byte_buffer_t *nas_msg);
void send_security_mode_complete();
void send_rrc_con_reconfig_complete();
void send_rrc_ue_cap_info();
@ -623,6 +623,7 @@ private:
void rrc_connection_release();
void radio_link_failure();
void leave_connected();
void stop_timers();
void apply_rr_config_common_dl(LIBLTE_RRC_RR_CONFIG_COMMON_STRUCT *config);
void apply_rr_config_common_ul(LIBLTE_RRC_RR_CONFIG_COMMON_STRUCT *config);

@ -73,7 +73,7 @@ void mux::reset()
bool mux::is_pending_any_sdu()
{
for (uint32_t i=0;i<lch.size();i++) {
if (rlc->get_buffer_state(lch[i].id)) {
if (rlc->has_data(lch[i].id)) {
return true;
}
}
@ -81,7 +81,7 @@ bool mux::is_pending_any_sdu()
}
bool mux::is_pending_sdu(uint32_t lch_id) {
return rlc->get_buffer_state(lch_id)>0;
return rlc->has_data(lch_id);
}
int mux::find_lchid(uint32_t lcid)
@ -307,11 +307,11 @@ bool mux::sched_sdu(lchid_t *ch, int *sdu_space, int max_sdu_sz)
bool mux::allocate_sdu(uint32_t lcid, srslte::sch_pdu* pdu_msg, int max_sdu_sz)
{
// Get n-th pending SDU pointer and length
bool sdu_added = false;
int sdu_len = rlc->get_buffer_state(lcid);
if (sdu_len > 0) { // there is pending SDU to allocate
while (sdu_len > 0) { // there is pending SDU to allocate
int buffer_state = sdu_len;
if (sdu_len > max_sdu_sz && max_sdu_sz >= 0) {
sdu_len = max_sdu_sz;
@ -326,7 +326,8 @@ bool mux::allocate_sdu(uint32_t lcid, srslte::sch_pdu* pdu_msg, int max_sdu_sz)
if (sdu_len > 0) { // new SDU could be added
Debug("SDU: allocated lcid=%d, rlc_buffer=%d, allocated=%d/%d, max_sdu_sz=%d, remaining=%d\n",
lcid, buffer_state, sdu_len, sdu_space, max_sdu_sz, pdu_msg->rem_size());
return true;
sdu_len = rlc->get_buffer_state(lcid);
sdu_added = true;
} else {
Warning("SDU: rlc_buffer=%d, allocated=%d/%d, remaining=%d\n",
buffer_state, sdu_len, sdu_space, pdu_msg->rem_size());
@ -335,7 +336,7 @@ bool mux::allocate_sdu(uint32_t lcid, srslte::sch_pdu* pdu_msg, int max_sdu_sz)
}
}
}
return false;
return sdu_added;
}
void mux::msg3_flush()

@ -104,10 +104,10 @@ bool bsr_proc::check_highest_channel() {
for (int i=0;i<MAX_LCID && pending_data_lcid == -1;i++) {
if (lcg[i] >= 0) {
if (rlc->get_buffer_state(i) > 0) {
if (rlc->has_data(i)) {
pending_data_lcid = i;
for (int j=0;j<MAX_LCID;j++) {
if (rlc->get_buffer_state(j) > 0) {
if (rlc->has_data(j)) {
if (priorities[j] > priorities[i]) {
pending_data_lcid = -1;
}
@ -148,7 +148,7 @@ bool bsr_proc::check_single_channel() {
for (int i=0;i<MAX_LCID;i++) {
if (lcg[i] >= 0) {
if (rlc->get_buffer_state(i) > 0) {
if (rlc->has_data(i)) {
pending_data_lcid = i;
nof_nonzero_lcid++;
}

@ -441,6 +441,7 @@ void phch_recv::run_thread()
if (!prach_ptr) {
Error("Generating PRACH\n");
}
set_time_adv_sec(0.0f);
}
/* Compute TX time: Any transmission happens in TTI+4 thus advance 4 ms the reception time */

@ -741,7 +741,7 @@ int phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload[SRSL
} else if (ue_dl.nof_rx_antennas > 1 && nof_tb == 2) {
mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
} else {
Error("Wrong combination of antennas (%d) or transport blocks (%d) for TM3\n", ue_dl.nof_rx_antennas,
Error("Wrong combination of antennas (%d) or transport blocks (%d) for TM4\n", ue_dl.nof_rx_antennas,
nof_tb);
valid_config = false;
}

@ -312,11 +312,11 @@ bool ue::switch_off() {
// wait for max. 5s for it to be sent (according to TS 24.301 Sec 25.5.2.2)
const uint32_t RB_ID_SRB1 = 1;
int cnt = 0, timeout = 5;
while (rlc.get_buffer_state(RB_ID_SRB1) && ++cnt <= timeout) {
while (rlc.has_data(RB_ID_SRB1) && ++cnt <= timeout) {
sleep(1);
}
bool detach_sent = true;
if (rlc.get_buffer_state(RB_ID_SRB1)) {
if (rlc.has_data(RB_ID_SRB1)) {
nas_log.warning("Detach couldn't be sent after %ds.\n", timeout);
detach_sent = false;
}

@ -381,6 +381,9 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) {
case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST:
parse_detach_request(lcid, pdu);
break;
case LIBLTE_MME_MSG_TYPE_EMM_STATUS:
parse_emm_status(lcid, pdu);
break;
default:
nas_log->error("Not handling NAS message with MSG_TYPE=%02X\n", msg_type);
pool->deallocate(pdu);
@ -830,7 +833,7 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) {
rrc->enable_capabilities();
nas_log->info("Sending Attach Complete\n");
rrc->write_sdu(lcid, pdu);
rrc->write_sdu(pdu);
ctxt.tx_count++;
} else {
nas_log->info("Not handling attach type %u\n", attach_accept.eps_attach_result);
@ -1042,7 +1045,7 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu)
nas_log->info("Sending Security Mode Complete nas_current_ctxt.tx_count=%d, RB=%s\n",
ctxt.tx_count,
rrc->get_rb_name(lcid).c_str());
rrc->write_sdu(lcid, pdu);
rrc->write_sdu(pdu);
ctxt.tx_count++;
}
@ -1089,6 +1092,32 @@ void nas::parse_detach_request(uint32_t lcid, byte_buffer_t *pdu)
}
}
void nas::parse_emm_status(uint32_t lcid, byte_buffer_t *pdu)
{
LIBLTE_MME_EMM_STATUS_MSG_STRUCT emm_status;
liblte_mme_unpack_emm_status_msg((LIBLTE_BYTE_MSG_STRUCT *)pdu, &emm_status);
ctxt.rx_count++;
pool->deallocate(pdu);
switch (emm_status.emm_cause) {
case LIBLTE_MME_ESM_CAUSE_INVALID_EPS_BEARER_IDENTITY:
nas_log->info("Received EMM status: Invalid EPS bearer identity\n");
// TODO: abort any ongoing procedure (see Sec. 6.7 in TS 24.301)
break;
case LIBLTE_MME_ESM_CAUSE_INVALID_PTI_VALUE:
nas_log->info("Received EMM status: Invalid PTI value\n");
// TODO: abort any ongoing procedure (see Sec. 6.7 in TS 24.301)
break;
case LIBLTE_MME_ESM_CAUSE_MESSAGE_TYPE_NON_EXISTENT_OR_NOT_IMPLEMENTED:
nas_log->info("Received EMM status: Invalid PTI value\n");
// TODO: see Sec. 6.7 in TS 24.301
break;
default:
nas_log->info("Received unknown EMM status (cause=%d)\n", emm_status.emm_cause);
break;
}
}
/*******************************************************************************
* Senders
******************************************************************************/
@ -1277,7 +1306,7 @@ void nas::send_security_mode_reject(uint8_t cause) {
pcap->write_nas(msg->msg, msg->N_bytes);
}
nas_log->info("Sending security mode reject\n");
rrc->write_sdu(cfg.lcid, msg);
rrc->write_sdu(msg);
}
void nas::send_detach_request(bool switch_off)
@ -1342,7 +1371,7 @@ void nas::send_detach_request(bool switch_off)
nas_log->info("Sending detach request\n");
if (rrc->is_connected()) {
rrc->write_sdu(cfg.lcid, pdu);
rrc->write_sdu(pdu);
} else {
rrc->connection_request(LIBLTE_RRC_CON_REQ_EST_CAUSE_MO_SIGNALLING, pdu);
}
@ -1381,7 +1410,7 @@ void nas::send_detach_accept()
}
nas_log->info("Sending detach accept\n");
rrc->write_sdu(cfg.lcid, pdu);
rrc->write_sdu(pdu);
}
@ -1416,7 +1445,7 @@ void nas::send_authentication_response(const uint8_t* res, const size_t res_len,
}
nas_log->info("Sending Authentication Response\n");
rrc->write_sdu(cfg.lcid, pdu);
rrc->write_sdu(pdu);
}
@ -1442,7 +1471,7 @@ void nas::send_authentication_failure(const uint8_t cause, const uint8_t* auth_f
pcap->write_nas(msg->msg, msg->N_bytes);
}
nas_log->info("Sending authentication failure.\n");
rrc->write_sdu(cfg.lcid, msg);
rrc->write_sdu(msg);
}
@ -1477,7 +1506,7 @@ void nas::send_identity_response(uint32_t lcid, uint8 id_type)
pcap->write_nas(pdu->msg, pdu->N_bytes);
}
rrc->write_sdu(lcid, pdu);
rrc->write_sdu(pdu);
ctxt.tx_count++;
}
@ -1513,7 +1542,7 @@ void nas::send_service_request() {
}
nas_log->info("Sending service request\n");
rrc->write_sdu(cfg.lcid, msg);
rrc->write_sdu(msg);
ctxt.tx_count++;
}
@ -1646,7 +1675,7 @@ void nas::send_esm_information_response(const uint8 proc_transaction_id) {
}
nas_log->info_hex(pdu->msg, pdu->N_bytes, "Sending ESM information response\n");
rrc->write_sdu(cfg.lcid, pdu);
rrc->write_sdu(pdu);
ctxt.tx_count++;
chap_id++;

@ -220,6 +220,7 @@ void rrc::init(phy_interface_rrc *phy_,
void rrc::stop() {
running = false;
stop_timers();
cmd_msg_t msg;
msg.command = cmd_msg_t::STOP;
cmd_q.push(msg);
@ -1396,9 +1397,11 @@ void rrc::send_con_setup_complete(byte_buffer_t *nas_msg) {
send_ul_dcch_msg(RB_ID_SRB1);
}
void rrc::send_ul_info_transfer(uint32_t lcid, byte_buffer_t *nas_msg) {
void rrc::send_ul_info_transfer(byte_buffer_t *nas_msg) {
bzero(&ul_dcch_msg, sizeof(LIBLTE_RRC_UL_DCCH_MSG_STRUCT));
uint32_t lcid = rlc->has_bearer(RB_ID_SRB2) ? RB_ID_SRB2 : RB_ID_SRB1;
rrc_log->debug("%s Preparing UL Info Transfer\n", get_rb_name(lcid).c_str());
// Prepare RX INFO packet
@ -1409,7 +1412,7 @@ void rrc::send_ul_info_transfer(uint32_t lcid, byte_buffer_t *nas_msg) {
pool->deallocate(nas_msg);
send_ul_dcch_msg(rlc->has_bearer(RB_ID_SRB2) ? RB_ID_SRB2 : RB_ID_SRB1);
send_ul_dcch_msg(lcid);
}
void rrc::send_security_mode_complete() {
@ -1654,10 +1657,7 @@ void rrc::leave_connected()
mac->reset();
set_phy_default();
set_mac_default();
mac_timers->timer_get(t301)->stop();
mac_timers->timer_get(t310)->stop();
mac_timers->timer_get(t311)->stop();
mac_timers->timer_get(t304)->stop();
stop_timers();
rrc_log->info("Going RRC_IDLE\n");
if (phy->cell_is_camping()) {
// Receive paging
@ -1667,10 +1667,14 @@ void rrc::leave_connected()
}
}
void rrc::stop_timers()
{
mac_timers->timer_get(t300)->stop();
mac_timers->timer_get(t301)->stop();
mac_timers->timer_get(t310)->stop();
mac_timers->timer_get(t311)->stop();
mac_timers->timer_get(t304)->stop();
}
/*******************************************************************************
*
@ -1930,14 +1934,14 @@ void rrc::send_ul_dcch_msg(uint32_t lcid)
}
}
void rrc::write_sdu(uint32_t lcid, byte_buffer_t *sdu) {
void rrc::write_sdu(byte_buffer_t *sdu) {
if (state == RRC_STATE_IDLE) {
rrc_log->warning("Received ULInformationTransfer SDU when in IDLE\n");
return;
}
rrc_log->info_hex(sdu->msg, sdu->N_bytes, "TX %s SDU", get_rb_name(lcid).c_str());
send_ul_info_transfer(lcid, sdu);
rrc_log->info_hex(sdu->msg, sdu->N_bytes, "TX SDU");
send_ul_info_transfer(sdu);
}
void rrc::write_pdu(uint32_t lcid, byte_buffer_t *pdu) {
@ -2611,7 +2615,10 @@ void rrc::handle_con_reest(LIBLTE_RRC_CONNECTION_REESTABLISHMENT_STRUCT *setup)
void rrc::add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg) {
// Setup PDCP
pdcp->add_bearer(srb_cnfg->srb_id, srslte_pdcp_config_t(true)); // Set PDCP config control flag
srslte_pdcp_config_t pdcp_cfg;
pdcp_cfg.is_control = true;
pdcp_cfg.bearer_id = srb_cnfg->srb_id;
pdcp->add_bearer(srb_cnfg->srb_id, pdcp_cfg);
if(RB_ID_SRB2 == srb_cnfg->srb_id) {
pdcp->config_security(srb_cnfg->srb_id, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo);
pdcp->enable_integrity(srb_cnfg->srb_id);
@ -2676,6 +2683,7 @@ void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg) {
// Setup PDCP
srslte_pdcp_config_t pdcp_cfg;
pdcp_cfg.is_data = true;
pdcp_cfg.bearer_id = drb_cnfg->drb_id;
if (drb_cnfg->pdcp_cnfg.rlc_um_pdcp_sn_size_present) {
if (LIBLTE_RRC_PDCP_SN_SIZE_7_BITS == drb_cnfg->pdcp_cnfg.rlc_um_pdcp_sn_size) {
pdcp_cfg.sn_len = 7;

@ -282,7 +282,7 @@ public:
sib2_period = 0;
send_ack = 0;
}
uint32_t get_total_buffer_state(uint32_t lcid) {
bool has_data(uint32_t lcid) {
return get_buffer_state(lcid);
}
uint32_t get_buffer_state(uint32_t lcid) {

@ -92,7 +92,7 @@ public:
plmns.plmn_id.mnc = mnc;
plmns.tac = 0xffff;
}
void write_sdu(uint32_t lcid, byte_buffer_t *sdu)
void write_sdu(byte_buffer_t *sdu)
{
last_sdu_len = sdu->N_bytes;
//printf("NAS generated SDU (len=%d):\n", sdu->N_bytes);

Loading…
Cancel
Save