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
...

@ -318,6 +318,7 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm") 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") message(STATUS "have ARM")
set(HAVE_NEON "True") set(HAVE_NEON "True")
else(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm") else(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")

@ -3,8 +3,29 @@
# Auto-updated by CMake with actual install path # Auto-updated by CMake with actual install path
SRSLTE_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}/${DATA_DIR}" SRSLTE_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}/${DATA_DIR}"
# Default folder where configs go # check if install mode has been provided
dest_folder="$HOME/.srs" 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(){ install_file(){
source_path="$SRSLTE_INSTALL_DIR/$1" source_path="$SRSLTE_INSTALL_DIR/$1"
@ -40,6 +61,9 @@ echo "Installing srsLTE configuration files:"
if [ ! -d "$dest_folder" ]; then if [ ! -d "$dest_folder" ]; then
echo " - Creating srsLTE config folder $dest_folder" echo " - Creating srsLTE config folder $dest_folder"
mkdir $dest_folder mkdir $dest_folder
if [ $? -ne 0 ]; then
exit
fi
fi fi

@ -35,9 +35,18 @@ bool config_exists(std::string &filename, std::string default_name)
{ {
std::ifstream conf(filename.c_str(), std::ios::in); std::ifstream conf(filename.c_str(), std::ios::in);
if(conf.fail()) { if(conf.fail()) {
const char *homedir = NULL; // try to find file in /etc/srslte
char full_path[256]; char full_path[256];
ZERO_OBJECT(full_path); ZERO_OBJECT(full_path);
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()) {
// try home folder
const char* homedir = NULL;
ZERO_OBJECT(full_path);
if ((homedir = getenv("HOME")) == NULL) { if ((homedir = getenv("HOME")) == NULL) {
homedir = getpwuid(getuid())->pw_dir; homedir = getpwuid(getuid())->pw_dir;
} }
@ -53,6 +62,7 @@ bool config_exists(std::string &filename, std::string default_name)
return false; return false;
} }
} }
}
return true; return true;
} }

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

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

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

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

@ -169,8 +169,8 @@ public:
virtual void write_sdu(byte_buffer_t *sdu, bool blocking) = 0; virtual void write_sdu(byte_buffer_t *sdu, bool blocking) = 0;
// MAC interface // MAC interface
virtual bool has_data() = 0;
virtual uint32_t get_buffer_state() = 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 int read_pdu(uint8_t *payload, uint32_t nof_bytes) = 0;
virtual void write_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); void write_sdu(byte_buffer_t *sdu, bool blocking);
// MAC interface // MAC interface
bool has_data();
uint32_t get_buffer_state(); uint32_t get_buffer_state();
uint32_t get_total_buffer_state();
int read_pdu(uint8_t *payload, uint32_t nof_bytes); int read_pdu(uint8_t *payload, uint32_t nof_bytes);
void write_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; unread_bytes = 0;
} }
bool is_empty() {
return queue.empty();
}
private: private:
bool is_empty() { return queue.empty(); }
block_queue<byte_buffer_t*> queue; block_queue<byte_buffer_t*> queue;
uint32_t unread_bytes; uint32_t unread_bytes;

@ -68,8 +68,8 @@ public:
void write_sdu(byte_buffer_t *sdu, bool blocking = true); void write_sdu(byte_buffer_t *sdu, bool blocking = true);
// MAC interface // MAC interface
bool has_data();
uint32_t get_buffer_state(); uint32_t get_buffer_state();
uint32_t get_total_buffer_state();
int read_pdu(uint8_t *payload, uint32_t nof_bytes); int read_pdu(uint8_t *payload, uint32_t nof_bytes);
void write_pdu(uint8_t *payload, uint32_t nof_bytes); void write_pdu(uint8_t *payload, uint32_t nof_bytes);
int get_increment_sequence_num(); int get_increment_sequence_num();
@ -96,7 +96,8 @@ private:
void try_write_sdu(byte_buffer_t *sdu); void try_write_sdu(byte_buffer_t *sdu);
uint32_t get_num_tx_bytes(); uint32_t get_num_tx_bytes();
void reset_metrics(); void reset_metrics();
uint32_t get_buffer_size_bytes(); bool has_data();
uint32_t get_buffer_state();
private: private:
byte_buffer_pool *pool; 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; odd = false;
}else if(LIBLTE_MME_MOBILE_ID_TYPE_TMSI == mobile_id->type_of_id){ }else if(LIBLTE_MME_MOBILE_ID_TYPE_TMSI == mobile_id->type_of_id){
id32 = mobile_id->tmsi; id32 = mobile_id->tmsi;
length = 4; length = 5;
odd = false; odd = false;
} }
}else{ }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_custom_target(gen_build_info COMMAND cmake -P ${CMAKE_BINARY_DIR}/SRSLTEbuildinfo.cmake)
add_dependencies(srslte_common gen_build_info) add_dependencies(srslte_common gen_build_info)
add_executable(arch_select arch_select.cc)
target_include_directories(srslte_common PUBLIC ${SEC_INCLUDE_DIRS}) target_include_directories(srslte_common PUBLIC ${SEC_INCLUDE_DIRS})
target_link_libraries(srslte_common ${SEC_LIBRARIES}) target_link_libraries(srslte_common ${SEC_LIBRARIES})
install(TARGETS srslte_common DESTINATION ${LIBRARY_DIR}) 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); double srate_khz = round(cur_tx_srate/1e3);
if (srate_khz == 1.92e3) { if (srate_khz == 1.92e3) {
nsamples = 54; // 6 PRB
nsamples = 94;
} else if (srate_khz == 3.84e3) { } else if (srate_khz == 3.84e3) {
nsamples = 69; // 15 PRB
nsamples = 94;
} else if (srate_khz == 5.76e3) { } else if (srate_khz == 5.76e3) {
nsamples = 93; // 25 PRB
nsamples = 92;
} else if (srate_khz == 11.52e3) { } else if (srate_khz == 11.52e3) {
nsamples = 120; // 50 PRB
nsamples = 171;
} else if (srate_khz == 15.36e3) { } else if (srate_khz == 15.36e3) {
nsamples = 131; // 75 PRB
nsamples = 171;
} else if (srate_khz == 23.04e3) { } else if (srate_khz == 23.04e3) {
nsamples = 150; // 100 PRB
nsamples = 171;
} else { } else {
/* Interpolate from known values */ /* 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); 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")) { } else if(!strcmp(srslte_rf_name(&rf_device), "lime")) {
double srate_khz = round(cur_tx_srate/1e3); double srate_khz = round(cur_tx_srate/1e3);
if (srate_khz == 1.92e3) { if (srate_khz == 1.92e3) {
nsamples = 70;// estimated nsamples = 76;
} else if (srate_khz == 3.84e3) { } else if (srate_khz == 3.84e3) {
nsamples = 76;//estimated nsamples = 76;
} else if (srate_khz == 5.76e3) { } else if (srate_khz == 5.76e3) {
nsamples = 76; nsamples = 76;
} else if (srate_khz == 11.52e3) { } else if (srate_khz == 11.52e3) {
nsamples = 76; nsamples = 76;
} else if (srate_khz == 15.36e3) { } else if (srate_khz == 15.36e3) {
nsamples = 73; nsamples = 76;
} else if (srate_khz == 23.04e3) { } else if (srate_khz == 23.04e3) {
nsamples = 87; nsamples = 76;
} else { } else {
/* Interpolate from known values */ /* 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); 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: case INTEGRITY_ALGORITHM_ID_128_EIA1:
security_128_eia1(&k_int[16], security_128_eia1(&k_int[16],
tx_count, tx_count,
get_bearer_id(lcid), cfg.bearer_id - 1,
cfg.direction, cfg.direction,
msg, msg,
msg_len, msg_len,
@ -253,7 +253,7 @@ void pdcp_entity::integrity_generate( uint8_t *msg,
case INTEGRITY_ALGORITHM_ID_128_EIA2: case INTEGRITY_ALGORITHM_ID_128_EIA2:
security_128_eia2(&k_int[16], security_128_eia2(&k_int[16],
tx_count, tx_count,
get_bearer_id(lcid), cfg.bearer_id - 1,
cfg.direction, cfg.direction,
msg, msg,
msg_len, msg_len,
@ -266,7 +266,7 @@ void pdcp_entity::integrity_generate( uint8_t *msg,
log->debug("Integrity gen input:\n"); log->debug("Integrity gen input:\n");
log->debug_hex(&k_int[16], 16, " K_int"); log->debug_hex(&k_int[16], 16, " K_int");
log->debug(" Local count: %d\n", tx_count); 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(" Direction: %s\n", (cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? "Downlink" : "Uplink");
log->debug_hex(msg, msg_len, " Message"); log->debug_hex(msg, msg_len, " Message");
log->debug_hex(mac, 4, "MAC (generated)"); 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: case INTEGRITY_ALGORITHM_ID_128_EIA1:
security_128_eia1(&k_int[16], security_128_eia1(&k_int[16],
count, count,
get_bearer_id(lcid), cfg.bearer_id - 1,
(cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK), (cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK),
msg, msg,
msg_len, msg_len,
@ -297,7 +297,7 @@ bool pdcp_entity::integrity_verify(uint8_t *msg,
case INTEGRITY_ALGORITHM_ID_128_EIA2: case INTEGRITY_ALGORITHM_ID_128_EIA2:
security_128_eia2(&k_int[16], security_128_eia2(&k_int[16],
count, count,
get_bearer_id(lcid), cfg.bearer_id - 1,
(cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK), (cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK),
msg, msg,
msg_len, msg_len,
@ -310,7 +310,7 @@ bool pdcp_entity::integrity_verify(uint8_t *msg,
log->debug("Integrity check input:\n"); log->debug("Integrity check input:\n");
log->debug_hex(&k_int[16], 16, " K_int"); log->debug_hex(&k_int[16], 16, " K_int");
log->debug(" Local count: %d\n", count); 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(" Direction: %s\n", (cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? "Uplink" : "Downlink");
log->debug_hex(msg, msg_len, " Message"); 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: case CIPHERING_ALGORITHM_ID_128_EEA1:
security_128_eea1(&(k_enc[16]), security_128_eea1(&(k_enc[16]),
tx_count, tx_count,
get_bearer_id(lcid), cfg.bearer_id - 1,
cfg.direction, cfg.direction,
msg, msg,
msg_len, msg_len,
@ -361,7 +361,7 @@ void pdcp_entity::cipher_encrypt(uint8_t *msg,
case CIPHERING_ALGORITHM_ID_128_EEA2: case CIPHERING_ALGORITHM_ID_128_EEA2:
security_128_eea2(&(k_enc[16]), security_128_eea2(&(k_enc[16]),
tx_count, tx_count,
get_bearer_id(lcid), cfg.bearer_id - 1,
cfg.direction, cfg.direction,
msg, msg,
msg_len, msg_len,
@ -386,7 +386,7 @@ void pdcp_entity::cipher_decrypt(uint8_t *ct,
case CIPHERING_ALGORITHM_ID_128_EEA1: case CIPHERING_ALGORITHM_ID_128_EEA1:
security_128_eea1(&(k_enc[16]), security_128_eea1(&(k_enc[16]),
count, count,
get_bearer_id(lcid), cfg.bearer_id - 1,
(cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK), (cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK),
ct, ct,
ct_len, ct_len,
@ -396,7 +396,7 @@ void pdcp_entity::cipher_decrypt(uint8_t *ct,
case CIPHERING_ALGORITHM_ID_128_EEA2: case CIPHERING_ALGORITHM_ID_128_EEA2:
security_128_eea2(&(k_enc[16]), security_128_eea2(&(k_enc[16]),
count, count,
get_bearer_id(lcid), cfg.bearer_id - 1,
(cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK), (cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK),
ct, ct,
ct_len, 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() uint32_t pdcp_entity::get_dl_count()
{ {
return rx_count; return rx_count;

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

@ -152,14 +152,14 @@ void rlc_am::write_sdu(byte_buffer_t *sdu, bool blocking)
* MAC interface * 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) 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(); 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); return (((do_status() && not status_prohibited)) || // if we have a status PDU to transmit
uint32_t n_bytes = 0; (not retx_queue.empty()) || // if we have a retransmission
uint32_t n_sdus = 0; (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
// 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;
} }
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); pthread_mutex_lock(&mutex);
uint32_t n_bytes = 0; uint32_t n_bytes = 0;
@ -385,11 +338,11 @@ uint32_t rlc_am::rlc_am_tx::get_total_buffer_state()
// Bytes needed for retx // Bytes needed for retx
if(not retx_queue.empty()) { if(not retx_queue.empty()) {
rlc_amd_retx_t retx = retx_queue.front(); 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)) { if(tx_window.end() != tx_window.find(retx.sn)) {
int req_bytes = required_buffer_size(retx); int req_bytes = required_buffer_size(retx);
if (req_bytes < 0) { 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(); retx_queue.pop_front();
} else { } else {
n_bytes += req_bytes; 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; n_bytes += ((n_sdus-1)*1.5)+0.5;
} }
// Room needed for fixed header? // Room needed for fixed header of data PDUs
if (n_bytes > 0) { if (n_bytes > 0 && n_sdus > 0) {
n_bytes += 3; 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); pthread_mutex_unlock(&mutex);

@ -123,14 +123,14 @@ void rlc_tm::write_sdu(byte_buffer_t *sdu, bool blocking)
} }
// MAC interface // 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() 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 * 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) 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 // Bytes needed for tx SDUs
uint32_t n_sdus = tx_sdu_queue.size(); 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); gtpu_log.set_hex_limit(args->log.gtpu_hex_limit);
s1ap_log.set_hex_limit(args->log.s1ap_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 // Set up pcap and trace
if(args->pcap.enable) if(args->pcap.enable)
{ {
@ -194,55 +244,6 @@ bool enb::init(all_args_t *args_)
radio.register_error_handler(rf_msg); 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 // Init all layers
phy.init(&args->expert.phy, &phy_cfg, &radio, &mac, phy_log); phy.init(&args->expert.phy, &phy_cfg, &radio, &mac, phy_log);
mac.init(&args->expert.mac, &cell_cfg, &phy, &rlc, &rrc, &mac_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) { if (sdu_space > 0) {
int sdu_len = SRSLTE_MIN(total_sdu_len, (uint32_t) sdu_space); int sdu_len = SRSLTE_MIN(total_sdu_len, (uint32_t) sdu_space);
int n=1; 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 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); 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); 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(users.count(rnti)) {
if(rnti != SRSLTE_MRNTI) { if(rnti != SRSLTE_MRNTI) {
ret = users[rnti].rlc->read_pdu(lcid, payload, nof_bytes); 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 { } else {
ret = users[rnti].rlc->read_pdu_mch(lcid, payload, nof_bytes); ret = users[rnti].rlc->read_pdu_mch(lcid, payload, nof_bytes);
tx_queue = users[rnti].rlc->get_total_mch_buffer_state(lcid); 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 // In the eNodeB, there is no polling for buffer state from the scheduler, thus
// communicate buffer state every time a new PDU is written // 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; uint32_t retx_queue = 0;
log_h->debug("Buffer state PDCP: rnti=0x%x, lcid=%d, tx_queue=%d\n", rnti, lcid, tx_queue); 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); 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 (users.count(rnti)) {
if(rnti != SRSLTE_MRNTI){ if(rnti != SRSLTE_MRNTI){
users[rnti].rlc->write_sdu(lcid, sdu, false); 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 { }else {
users[rnti].rlc->write_sdu_mch(lcid, sdu); users[rnti].rlc->write_sdu_mch(lcid, sdu);
tx_queue = users[rnti].rlc->get_total_mch_buffer_state(lcid); 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 // Configure SRB1 in PDCP
srslte::srslte_pdcp_config_t pdcp_cnfg; srslte::srslte_pdcp_config_t pdcp_cnfg;
pdcp_cnfg.bearer_id = 1;
pdcp_cnfg.is_control = true; pdcp_cnfg.is_control = true;
pdcp_cnfg.direction = SECURITY_DIRECTION_DOWNLINK; pdcp_cnfg.direction = SECURITY_DIRECTION_DOWNLINK;
parent->pdcp->add_bearer(rnti, 1, pdcp_cnfg); 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 // Configure SRB2 in PDCP
srslte::srslte_pdcp_config_t pdcp_cnfg; srslte::srslte_pdcp_config_t pdcp_cnfg;
pdcp_cnfg.bearer_id = 2;
pdcp_cnfg.direction = SECURITY_DIRECTION_DOWNLINK; pdcp_cnfg.direction = SECURITY_DIRECTION_DOWNLINK;
pdcp_cnfg.is_control = true; pdcp_cnfg.is_control = true;
pdcp_cnfg.is_data = false; 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 // Configure DRB in RLC
parent->rlc->add_bearer(rnti, lcid, &conn_reconf->rr_cnfg_ded.drb_to_add_mod_list[i].rlc_cnfg); parent->rlc->add_bearer(rnti, lcid, &conn_reconf->rr_cnfg_ded.drb_to_add_mod_list[i].rlc_cnfg);
// Configure DRB in PDCP // 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 // DRB has already been configured in GTPU through bearer setup
// Add NAS message // Add NAS message

@ -181,6 +181,7 @@ private:
void parse_esm_information_request(uint32_t lcid, byte_buffer_t *pdu); 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_emm_information(uint32_t lcid, byte_buffer_t *pdu);
void parse_detach_request(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 // Packet generators
void gen_attach_request(byte_buffer_t *msg); void gen_attach_request(byte_buffer_t *msg);

@ -290,7 +290,7 @@ public:
bool mbms_service_start(uint32_t serv, uint32_t port); bool mbms_service_start(uint32_t serv, uint32_t port);
// NAS interface // NAS interface
void write_sdu(uint32_t lcid, byte_buffer_t *sdu); void write_sdu(byte_buffer_t *sdu);
void enable_capabilities(); void enable_capabilities();
uint16_t get_mcc(); uint16_t get_mcc();
uint16_t get_mnc(); 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_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause);
void send_con_restablish_complete(); void send_con_restablish_complete();
void send_con_setup_complete(byte_buffer_t *nas_msg); 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_security_mode_complete();
void send_rrc_con_reconfig_complete(); void send_rrc_con_reconfig_complete();
void send_rrc_ue_cap_info(); void send_rrc_ue_cap_info();
@ -623,6 +623,7 @@ private:
void rrc_connection_release(); void rrc_connection_release();
void radio_link_failure(); void radio_link_failure();
void leave_connected(); void leave_connected();
void stop_timers();
void apply_rr_config_common_dl(LIBLTE_RRC_RR_CONFIG_COMMON_STRUCT *config); 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); 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() bool mux::is_pending_any_sdu()
{ {
for (uint32_t i=0;i<lch.size();i++) { 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; return true;
} }
} }
@ -81,7 +81,7 @@ bool mux::is_pending_any_sdu()
} }
bool mux::is_pending_sdu(uint32_t lch_id) { 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) 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) bool mux::allocate_sdu(uint32_t lcid, srslte::sch_pdu* pdu_msg, int max_sdu_sz)
{ {
// Get n-th pending SDU pointer and length // Get n-th pending SDU pointer and length
bool sdu_added = false;
int sdu_len = rlc->get_buffer_state(lcid); 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; int buffer_state = sdu_len;
if (sdu_len > max_sdu_sz && max_sdu_sz >= 0) { if (sdu_len > max_sdu_sz && max_sdu_sz >= 0) {
sdu_len = max_sdu_sz; 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 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", 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()); 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 { } else {
Warning("SDU: rlc_buffer=%d, allocated=%d/%d, remaining=%d\n", Warning("SDU: rlc_buffer=%d, allocated=%d/%d, remaining=%d\n",
buffer_state, sdu_len, sdu_space, pdu_msg->rem_size()); 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() 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++) { for (int i=0;i<MAX_LCID && pending_data_lcid == -1;i++) {
if (lcg[i] >= 0) { if (lcg[i] >= 0) {
if (rlc->get_buffer_state(i) > 0) { if (rlc->has_data(i)) {
pending_data_lcid = i; pending_data_lcid = i;
for (int j=0;j<MAX_LCID;j++) { 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]) { if (priorities[j] > priorities[i]) {
pending_data_lcid = -1; pending_data_lcid = -1;
} }
@ -148,7 +148,7 @@ bool bsr_proc::check_single_channel() {
for (int i=0;i<MAX_LCID;i++) { for (int i=0;i<MAX_LCID;i++) {
if (lcg[i] >= 0) { if (lcg[i] >= 0) {
if (rlc->get_buffer_state(i) > 0) { if (rlc->has_data(i)) {
pending_data_lcid = i; pending_data_lcid = i;
nof_nonzero_lcid++; nof_nonzero_lcid++;
} }

@ -441,6 +441,7 @@ void phch_recv::run_thread()
if (!prach_ptr) { if (!prach_ptr) {
Error("Generating PRACH\n"); 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 */ /* 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) { } else if (ue_dl.nof_rx_antennas > 1 && nof_tb == 2) {
mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX; mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
} else { } 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); nof_tb);
valid_config = false; 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) // 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; const uint32_t RB_ID_SRB1 = 1;
int cnt = 0, timeout = 5; 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); sleep(1);
} }
bool detach_sent = true; 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); nas_log.warning("Detach couldn't be sent after %ds.\n", timeout);
detach_sent = false; 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: case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST:
parse_detach_request(lcid, pdu); parse_detach_request(lcid, pdu);
break; break;
case LIBLTE_MME_MSG_TYPE_EMM_STATUS:
parse_emm_status(lcid, pdu);
break;
default: default:
nas_log->error("Not handling NAS message with MSG_TYPE=%02X\n", msg_type); nas_log->error("Not handling NAS message with MSG_TYPE=%02X\n", msg_type);
pool->deallocate(pdu); pool->deallocate(pdu);
@ -830,7 +833,7 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) {
rrc->enable_capabilities(); rrc->enable_capabilities();
nas_log->info("Sending Attach Complete\n"); nas_log->info("Sending Attach Complete\n");
rrc->write_sdu(lcid, pdu); rrc->write_sdu(pdu);
ctxt.tx_count++; ctxt.tx_count++;
} else { } else {
nas_log->info("Not handling attach type %u\n", attach_accept.eps_attach_result); 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", nas_log->info("Sending Security Mode Complete nas_current_ctxt.tx_count=%d, RB=%s\n",
ctxt.tx_count, ctxt.tx_count,
rrc->get_rb_name(lcid).c_str()); rrc->get_rb_name(lcid).c_str());
rrc->write_sdu(lcid, pdu); rrc->write_sdu(pdu);
ctxt.tx_count++; 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 * Senders
******************************************************************************/ ******************************************************************************/
@ -1277,7 +1306,7 @@ void nas::send_security_mode_reject(uint8_t cause) {
pcap->write_nas(msg->msg, msg->N_bytes); pcap->write_nas(msg->msg, msg->N_bytes);
} }
nas_log->info("Sending security mode reject\n"); 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) 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"); nas_log->info("Sending detach request\n");
if (rrc->is_connected()) { if (rrc->is_connected()) {
rrc->write_sdu(cfg.lcid, pdu); rrc->write_sdu(pdu);
} else { } else {
rrc->connection_request(LIBLTE_RRC_CON_REQ_EST_CAUSE_MO_SIGNALLING, pdu); 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"); 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"); 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); pcap->write_nas(msg->msg, msg->N_bytes);
} }
nas_log->info("Sending authentication failure.\n"); 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); pcap->write_nas(pdu->msg, pdu->N_bytes);
} }
rrc->write_sdu(lcid, pdu); rrc->write_sdu(pdu);
ctxt.tx_count++; ctxt.tx_count++;
} }
@ -1513,7 +1542,7 @@ void nas::send_service_request() {
} }
nas_log->info("Sending service request\n"); nas_log->info("Sending service request\n");
rrc->write_sdu(cfg.lcid, msg); rrc->write_sdu(msg);
ctxt.tx_count++; 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"); 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++; ctxt.tx_count++;
chap_id++; chap_id++;

@ -220,6 +220,7 @@ void rrc::init(phy_interface_rrc *phy_,
void rrc::stop() { void rrc::stop() {
running = false; running = false;
stop_timers();
cmd_msg_t msg; cmd_msg_t msg;
msg.command = cmd_msg_t::STOP; msg.command = cmd_msg_t::STOP;
cmd_q.push(msg); 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); 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)); 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()); rrc_log->debug("%s Preparing UL Info Transfer\n", get_rb_name(lcid).c_str());
// Prepare RX INFO packet // 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); 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() { void rrc::send_security_mode_complete() {
@ -1654,10 +1657,7 @@ void rrc::leave_connected()
mac->reset(); mac->reset();
set_phy_default(); set_phy_default();
set_mac_default(); set_mac_default();
mac_timers->timer_get(t301)->stop(); stop_timers();
mac_timers->timer_get(t310)->stop();
mac_timers->timer_get(t311)->stop();
mac_timers->timer_get(t304)->stop();
rrc_log->info("Going RRC_IDLE\n"); rrc_log->info("Going RRC_IDLE\n");
if (phy->cell_is_camping()) { if (phy->cell_is_camping()) {
// Receive paging // 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) { if (state == RRC_STATE_IDLE) {
rrc_log->warning("Received ULInformationTransfer SDU when in IDLE\n"); rrc_log->warning("Received ULInformationTransfer SDU when in IDLE\n");
return; return;
} }
rrc_log->info_hex(sdu->msg, sdu->N_bytes, "TX %s SDU", get_rb_name(lcid).c_str()); rrc_log->info_hex(sdu->msg, sdu->N_bytes, "TX SDU");
send_ul_info_transfer(lcid, sdu); send_ul_info_transfer(sdu);
} }
void rrc::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { 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) { void rrc::add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg) {
// Setup PDCP // 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) { 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->config_security(srb_cnfg->srb_id, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo);
pdcp->enable_integrity(srb_cnfg->srb_id); 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 // Setup PDCP
srslte_pdcp_config_t pdcp_cfg; srslte_pdcp_config_t pdcp_cfg;
pdcp_cfg.is_data = true; 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 (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) { if (LIBLTE_RRC_PDCP_SN_SIZE_7_BITS == drb_cnfg->pdcp_cnfg.rlc_um_pdcp_sn_size) {
pdcp_cfg.sn_len = 7; pdcp_cfg.sn_len = 7;

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

@ -92,7 +92,7 @@ public:
plmns.plmn_id.mnc = mnc; plmns.plmn_id.mnc = mnc;
plmns.tac = 0xffff; 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; last_sdu_len = sdu->N_bytes;
//printf("NAS generated SDU (len=%d):\n", sdu->N_bytes); //printf("NAS generated SDU (len=%d):\n", sdu->N_bytes);

Loading…
Cancel
Save