Merge branch 'next' of github.com:softwareradiosystems/srsLTE into next

master
Pedro Alvarez 7 years ago
commit e123d447ff

@ -231,12 +231,6 @@ endmacro(ADD_CXX_COMPILER_FLAG_IF_AVAILABLE)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${GCC_ARCH} -Wall -Wno-comment -Wno-reorder -Wno-unused-but-set-variable -Wno-unused-variable -std=c++03") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${GCC_ARCH} -Wall -Wno-comment -Wno-reorder -Wno-unused-but-set-variable -Wno-unused-variable -std=c++03")
if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -DDEBUG_MODE")
else(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
endif(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
find_package(SSE) find_package(SSE)
if (HAVE_AVX2) if (HAVE_AVX2)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse -mavx2 -DLV_HAVE_AVX2 -DLV_HAVE_AVX -DLV_HAVE_SSE") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse -mavx2 -DLV_HAVE_AVX2 -DLV_HAVE_AVX -DLV_HAVE_SSE")
@ -255,16 +249,18 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=${GCC_ARCH} -Wall -Wno-comment -Wno-write-strings -Wno-format-extra-args -Winline -Wno-unused-result -Wno-format -std=c99 -D_GNU_SOURCE") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=${GCC_ARCH} -Wall -Wno-comment -Wno-write-strings -Wno-format-extra-args -Winline -Wno-unused-result -Wno-format -std=c99 -D_GNU_SOURCE")
if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -DDEBUG_MODE") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb -O0 -DDEBUG_MODE -DBUILD_TYPE_DEBUG")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -O0 -DDEBUG_MODE -DBUILD_TYPE_DEBUG")
else(${CMAKE_BUILD_TYPE} STREQUAL "Debug") else(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
if(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") if(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG_MODE") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb -DBUILD_TYPE_RELWITHDEBINFO")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -DBUILD_TYPE_RELWITHDEBINFO")
else(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") else(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -DBUILD_TYPE_RELEASE")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -DBUILD_TYPE_RELEASE")
endif(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") endif(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo")
endif(${CMAKE_BUILD_TYPE} STREQUAL "Debug") endif(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
if (USE_LTE_RATES) if (USE_LTE_RATES)
message(STATUS "Using standard LTE sampling rates") message(STATUS "Using standard LTE sampling rates")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFORCE_STANDARD_RATE") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFORCE_STANDARD_RATE")

@ -32,10 +32,18 @@
extern "C" { extern "C" {
# endif # endif
#ifdef NDEBUG #ifdef BUILD_TYPE_RELEASE
static char build_mode[] = "Release"; static char build_mode[] = "Release";
#else #else
#ifdef BUILD_TYPE_DEBUG
static char build_mode[] = "Debug"; static char build_mode[] = "Debug";
#else
#ifdef BUILD_TYPE_RELWITHDEBINFO
static char build_mode[] = "RelWithDebInfo";
#else
static char build_mode[] = "unknown";
#endif
#endif
#endif #endif
// the configured build options for srsLTE // the configured build options for srsLTE

@ -133,11 +133,15 @@ public:
// Section 6.1.2 // Section 6.1.2
void parse_packet(uint8_t *ptr) { void parse_packet(uint8_t *ptr) {
uint8_t *init_ptr = ptr; uint8_t *init_ptr = ptr;
nof_subheaders = 0; nof_subheaders = 0;
while(subheaders[nof_subheaders].read_subheader(&ptr)) { bool ret = false;
nof_subheaders++; do {
} if (nof_subheaders < (int)max_subheaders) {
nof_subheaders++; ret = subheaders[nof_subheaders].read_subheader(&ptr);
nof_subheaders++;
}
} while (ret && (nof_subheaders + 1) < (int)max_subheaders);
for (int i=0;i<nof_subheaders;i++) { for (int i=0;i<nof_subheaders;i++) {
subheaders[i].read_payload(&ptr); subheaders[i].read_payload(&ptr);
} }

@ -11771,7 +11771,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_rrc_connection_reject_msg(LIBLTE_RRC_CONNECTIO
liblte_value_2_bits(0, &msg_ptr, 1); liblte_value_2_bits(0, &msg_ptr, 1);
// Wait Time // Wait Time
liblte_value_2_bits(con_rej->wait_time, &msg_ptr, 4); liblte_value_2_bits(con_rej->wait_time - 1, &msg_ptr, 4);
// Fill in the number of bits used // Fill in the number of bits used
msg->N_bits = msg_ptr - msg->msg; msg->N_bits = msg_ptr - msg->msg;
@ -11800,7 +11800,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_reject_msg(LIBLTE_BIT_MSG_STR
liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);;
// Wait Time // Wait Time
con_rej->wait_time = liblte_bits_2_value(&msg_ptr, 4); con_rej->wait_time = liblte_bits_2_value(&msg_ptr, 4) + 1;
liblte_rrc_consume_noncrit_extension(ext, __func__, &msg_ptr); liblte_rrc_consume_noncrit_extension(ext, __func__, &msg_ptr);

@ -122,7 +122,7 @@ uint8_t* sch_pdu::write_packet(srslte::log *log_h)
sch_subh padding; sch_subh padding;
padding.set_padding(); padding.set_padding();
if (nof_subheaders <= 0) { if (nof_subheaders <= 0 && nof_subheaders < (int)max_subheaders) {
log_h->error("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders); log_h->error("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders);
log_h->console("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders); log_h->console("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders);
return NULL; return NULL;

@ -1072,7 +1072,9 @@ int field_qci::parse(libconfig::Setting &root)
parser::field_enum_num<LIBLTE_RRC_SN_FIELD_LENGTH_ENUM,uint8> sn_field_len parser::field_enum_num<LIBLTE_RRC_SN_FIELD_LENGTH_ENUM,uint8> sn_field_len
("sn_field_length", &rlc_cfg->sn_field_len, ("sn_field_length", &rlc_cfg->sn_field_len,
liblte_rrc_sn_field_length_num, LIBLTE_RRC_SN_FIELD_LENGTH_N_ITEMS); liblte_rrc_sn_field_length_num, LIBLTE_RRC_SN_FIELD_LENGTH_N_ITEMS);
sn_field_len.parse(q["rlc_config"]["ul_um"]); if (sn_field_len.parse(q["rlc_config"]["ul_um"])) {
fprintf(stderr, "Error can't find sn_field_length in section ul_um\n");
}
} }
if (q["rlc_config"].exists("dl_um")) { if (q["rlc_config"].exists("dl_um")) {
@ -1085,12 +1087,16 @@ int field_qci::parse(libconfig::Setting &root)
parser::field_enum_num<LIBLTE_RRC_SN_FIELD_LENGTH_ENUM,uint8> sn_field_len parser::field_enum_num<LIBLTE_RRC_SN_FIELD_LENGTH_ENUM,uint8> sn_field_len
("sn_field_length", &rlc_cfg->sn_field_len, ("sn_field_length", &rlc_cfg->sn_field_len,
liblte_rrc_sn_field_length_num, LIBLTE_RRC_SN_FIELD_LENGTH_N_ITEMS); liblte_rrc_sn_field_length_num, LIBLTE_RRC_SN_FIELD_LENGTH_N_ITEMS);
sn_field_len.parse(q["rlc_config"]["dl_um"]); if (sn_field_len.parse(q["rlc_config"]["dl_um"])) {
fprintf(stderr, "Error can't find sn_field_length in section dl_um\n");
}
parser::field_enum_num<LIBLTE_RRC_T_REORDERING_ENUM,int32> t_reordering parser::field_enum_num<LIBLTE_RRC_T_REORDERING_ENUM,int32> t_reordering
("t_reordering", &rlc_cfg->t_reordering, ("t_reordering", &rlc_cfg->t_reordering,
liblte_rrc_t_reordering_num, LIBLTE_RRC_T_REORDERING_N_ITEMS); liblte_rrc_t_reordering_num, LIBLTE_RRC_T_REORDERING_N_ITEMS);
t_reordering.parse(q["rlc_config"]["dl_um"]); if (t_reordering.parse(q["rlc_config"]["dl_um"])) {
fprintf(stderr, "Error can't find t_reordering in section dl_um\n");
}
} }
// Parse RLC-AM section // Parse RLC-AM section
@ -1100,22 +1106,30 @@ int field_qci::parse(libconfig::Setting &root)
parser::field_enum_num<LIBLTE_RRC_T_POLL_RETRANSMIT_ENUM,int32> t_poll_retx parser::field_enum_num<LIBLTE_RRC_T_POLL_RETRANSMIT_ENUM,int32> t_poll_retx
("t_poll_retx", &rlc_cfg->t_poll_retx, ("t_poll_retx", &rlc_cfg->t_poll_retx,
liblte_rrc_t_poll_retransmit_num, LIBLTE_RRC_T_POLL_RETRANSMIT_N_ITEMS); liblte_rrc_t_poll_retransmit_num, LIBLTE_RRC_T_POLL_RETRANSMIT_N_ITEMS);
t_poll_retx.parse(q["rlc_config"]["ul_am"]); if (t_poll_retx.parse(q["rlc_config"]["ul_am"])) {
fprintf(stderr, "Error can't find t_poll_retx in section ul_am\n");
}
parser::field_enum_num<LIBLTE_RRC_POLL_PDU_ENUM,int32> poll_pdu parser::field_enum_num<LIBLTE_RRC_POLL_PDU_ENUM,int32> poll_pdu
("poll_pdu", &rlc_cfg->poll_pdu, ("poll_pdu", &rlc_cfg->poll_pdu,
liblte_rrc_poll_pdu_num, LIBLTE_RRC_POLL_PDU_N_ITEMS); liblte_rrc_poll_pdu_num, LIBLTE_RRC_POLL_PDU_N_ITEMS);
poll_pdu.parse(q["rlc_config"]["ul_am"]); if (poll_pdu.parse(q["rlc_config"]["ul_am"])) {
fprintf(stderr, "Error can't find poll_pdu in section ul_am\n");
}
parser::field_enum_num<LIBLTE_RRC_POLL_BYTE_ENUM,int32> poll_byte parser::field_enum_num<LIBLTE_RRC_POLL_BYTE_ENUM,int32> poll_byte
("poll_byte", &rlc_cfg->poll_byte, ("poll_byte", &rlc_cfg->poll_byte,
liblte_rrc_poll_byte_num, LIBLTE_RRC_POLL_BYTE_N_ITEMS); liblte_rrc_poll_byte_num, LIBLTE_RRC_POLL_BYTE_N_ITEMS);
poll_byte.parse(q["rlc_config"]["ul_am"]); if (poll_byte.parse(q["rlc_config"]["ul_am"])) {
fprintf(stderr, "Error can't find poll_byte in section ul_am\n");
}
parser::field_enum_num<LIBLTE_RRC_MAX_RETX_THRESHOLD_ENUM,uint32_t> max_retx_thresh parser::field_enum_num<LIBLTE_RRC_MAX_RETX_THRESHOLD_ENUM,uint32_t> max_retx_thresh
("max_retx_thresh", &rlc_cfg->max_retx_thresh, ("max_retx_thresh", &rlc_cfg->max_retx_thresh,
liblte_rrc_max_retx_threshold_num, LIBLTE_RRC_MAX_RETX_THRESHOLD_N_ITEMS); liblte_rrc_max_retx_threshold_num, LIBLTE_RRC_MAX_RETX_THRESHOLD_N_ITEMS);
max_retx_thresh.parse(q["rlc_config"]["ul_am"]); if (max_retx_thresh.parse(q["rlc_config"]["ul_am"])) {
fprintf(stderr, "Error can't find max_retx_thresh in section ul_am\n");
}
} }
if (q["rlc_config"].exists("dl_am")) { if (q["rlc_config"].exists("dl_am")) {
@ -1124,12 +1138,16 @@ int field_qci::parse(libconfig::Setting &root)
parser::field_enum_num<LIBLTE_RRC_T_REORDERING_ENUM,int32> t_reordering parser::field_enum_num<LIBLTE_RRC_T_REORDERING_ENUM,int32> t_reordering
("t_reordering", &rlc_cfg->t_reordering, ("t_reordering", &rlc_cfg->t_reordering,
liblte_rrc_t_reordering_num, LIBLTE_RRC_T_REORDERING_N_ITEMS); liblte_rrc_t_reordering_num, LIBLTE_RRC_T_REORDERING_N_ITEMS);
t_reordering.parse(q["rlc_config"]["dl_am"]); if (t_reordering.parse(q["rlc_config"]["dl_am"])) {
fprintf(stderr, "Error can't find t_reordering in section dl_am\n");
}
parser::field_enum_num<LIBLTE_RRC_T_STATUS_PROHIBIT_ENUM,int32> t_status_prohibit parser::field_enum_num<LIBLTE_RRC_T_STATUS_PROHIBIT_ENUM,int32> t_status_prohibit
("t_status_prohibit", &rlc_cfg->t_status_prohibit, ("t_status_prohibit", &rlc_cfg->t_status_prohibit,
liblte_rrc_t_status_prohibit_num, LIBLTE_RRC_T_STATUS_PROHIBIT_N_ITEMS); liblte_rrc_t_status_prohibit_num, LIBLTE_RRC_T_STATUS_PROHIBIT_N_ITEMS);
t_status_prohibit.parse(q["rlc_config"]["dl_am"]); if (t_status_prohibit.parse(q["rlc_config"]["dl_am"])) {
fprintf(stderr, "Error can't find t_status_prohibit in section dl_am\n");
}
} }
@ -1141,17 +1159,23 @@ int field_qci::parse(libconfig::Setting &root)
LIBLTE_RRC_UL_SPECIFIC_PARAMETERS_STRUCT *lc_cfg = &cfg[qci].lc_cfg; LIBLTE_RRC_UL_SPECIFIC_PARAMETERS_STRUCT *lc_cfg = &cfg[qci].lc_cfg;
parser::field<uint8> priority ("priority", &lc_cfg->priority); parser::field<uint8> priority ("priority", &lc_cfg->priority);
priority.parse(q["logical_channel_config"]); if (priority.parse(q["logical_channel_config"])) {
fprintf(stderr, "Error can't find logical_channel_config in section priority\n");
}
parser::field_enum_num<LIBLTE_RRC_PRIORITIZED_BIT_RATE_ENUM,int32> prioritized_bit_rate parser::field_enum_num<LIBLTE_RRC_PRIORITIZED_BIT_RATE_ENUM,int32> prioritized_bit_rate
("prioritized_bit_rate", &lc_cfg->prioritized_bit_rate, ("prioritized_bit_rate", &lc_cfg->prioritized_bit_rate,
liblte_rrc_prioritized_bit_rate_num, LIBLTE_RRC_PRIORITIZED_BIT_RATE_N_ITEMS); liblte_rrc_prioritized_bit_rate_num, LIBLTE_RRC_PRIORITIZED_BIT_RATE_N_ITEMS);
prioritized_bit_rate.parse(q["logical_channel_config"]); if (prioritized_bit_rate.parse(q["logical_channel_config"])) {
fprintf(stderr, "Error can't find prioritized_bit_rate in section logical_channel_config\n");
}
parser::field_enum_num<LIBLTE_RRC_BUCKET_SIZE_DURATION_ENUM,int16> bucket_size_duration parser::field_enum_num<LIBLTE_RRC_BUCKET_SIZE_DURATION_ENUM,int16> bucket_size_duration
("bucket_size_duration", &lc_cfg->bucket_size_duration, ("bucket_size_duration", &lc_cfg->bucket_size_duration,
liblte_rrc_bucket_size_duration_num, LIBLTE_RRC_BUCKET_SIZE_DURATION_N_ITEMS); liblte_rrc_bucket_size_duration_num, LIBLTE_RRC_BUCKET_SIZE_DURATION_N_ITEMS);
bucket_size_duration.parse(q["logical_channel_config"]); if (bucket_size_duration.parse(q["logical_channel_config"])) {
fprintf(stderr, "Error can't find bucket_size_duration in section logical_channel_config\n");
}
parser::field<uint8> log_chan_group ("log_chan_group", &lc_cfg->log_chan_group); parser::field<uint8> log_chan_group ("log_chan_group", &lc_cfg->log_chan_group);
if (log_chan_group.parse(q["logical_channel_config"])) { if (log_chan_group.parse(q["logical_channel_config"])) {

@ -254,18 +254,22 @@ uint32_t sched::get_ul_buffer(uint16_t rnti)
return ret; return ret;
} }
/* \Warning: This function is not mutexed because it can produce late changes on the buffer state while
* the scheduler is already allocating data, resulting in empty grants.
* Ideally we would like the scheduler to query the RLC for buffer states in order to get the most updated
* buffer state with the minimum overhead. However, the current architecture is designed to be compliant
* with the FAPI interface
*/
int sched::dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) int sched::dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue)
{ {
pthread_mutex_lock(&mutex); int ret = 0;
int ret = 0; if (ue_db.count(rnti)) {
if (ue_db.count(rnti)) {
ue_db[rnti].dl_buffer_state(lc_id, tx_queue, retx_queue); ue_db[rnti].dl_buffer_state(lc_id, tx_queue, retx_queue);
} else { } else {
Error("User rnti=0x%x not found\n", rnti); Error("User rnti=0x%x not found\n", rnti);
ret = -1; ret = -1;
} }
pthread_mutex_unlock(&mutex); return ret;
return ret;
} }
int sched::dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code) int sched::dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code)
@ -676,10 +680,11 @@ int sched::dl_sched_data(dl_sched_data_t data[MAX_DATA_LIST])
int nof_data_elems = 0; int nof_data_elems = 0;
for(std::map<uint16_t, sched_ue>::iterator iter=ue_db.begin(); iter!=ue_db.end(); ++iter) { for(std::map<uint16_t, sched_ue>::iterator iter=ue_db.begin(); iter!=ue_db.end(); ++iter) {
sched_ue *user = (sched_ue*) &iter->second; sched_ue *user = (sched_ue*) &iter->second;
uint16_t rnti = (uint16_t) iter->first; uint16_t rnti = (uint16_t) iter->first;
dl_harq_proc *h = dl_metric->get_user_allocation(user); uint32_t data_before = user->get_pending_dl_new_data(current_tti);
dl_harq_proc *h = dl_metric->get_user_allocation(user);
srslte_dci_format_t dci_format = user->get_dci_format(); srslte_dci_format_t dci_format = user->get_dci_format();
data[nof_data_elems].dci_format = dci_format; data[nof_data_elems].dci_format = dci_format;
@ -706,10 +711,12 @@ int sched::dl_sched_data(dl_sched_data_t data[MAX_DATA_LIST])
Error("DCI format (%d) not implemented\n", dci_format); Error("DCI format (%d) not implemented\n", dci_format);
} }
if (tbs > 0) { if (tbs > 0) {
log_h->info("SCHED: DL %s rnti=0x%x, pid=%d, mask=0x%x, dci=%d,%d, n_rtx=%d, tbs=%d, buffer=%d, tb_en={%s,%s}\n", log_h->info("SCHED: DL %s rnti=0x%x, pid=%d, mask=0x%x, dci=%d,%d, n_rtx=%d, tbs=%d, buffer=%d/%d, tb_en={%s,%s}\n",
!is_newtx?"retx":"tx", rnti, h->get_id(), h->get_rbgmask(), !is_newtx?"retx":"tx", rnti, h->get_id(), h->get_rbgmask(),
data[nof_data_elems].dci_location.L, data[nof_data_elems].dci_location.ncce, h->nof_retx(0) + h->nof_retx(1), data[nof_data_elems].dci_location.L, data[nof_data_elems].dci_location.ncce, h->nof_retx(0) + h->nof_retx(1),
tbs, user->get_pending_dl_new_data(current_tti), data[nof_data_elems].dci.tb_en[0]?"y":"n", tbs,
data_before, user->get_pending_dl_new_data(current_tti),
data[nof_data_elems].dci.tb_en[0]?"y":"n",
data[nof_data_elems].dci.tb_en[1]?"y":"n"); data[nof_data_elems].dci.tb_en[1]?"y":"n");
nof_data_elems++; nof_data_elems++;
} else { } else {

@ -148,9 +148,7 @@ dl_harq_proc* dl_metric_rr::get_user_allocation(sched_ue *user)
if (pending_data || (h && !h->is_empty())) { if (pending_data || (h && !h->is_empty())) {
#endif #endif
if (nof_users_with_data) { if (nof_users_with_data) {
if (nof_users_with_data == 2) { if ((current_tti%nof_users_with_data) != user->ue_idx) {
}
if ((current_tti%nof_users_with_data) != user->ue_idx) {
return NULL; return NULL;
} }
} }

@ -1150,7 +1150,7 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in
offset = found_best?best_test_offset:offset; offset = found_best?best_test_offset:offset;
#endif #endif
if (offset >= 0 && offset < (int) sf_len*max_sf) { if (offset >= 0 && offset < (int)(sf_len*max_sf)) {
uint32_t nof_sf = (sf_len*max_sf - offset)/sf_len; uint32_t nof_sf = (sf_len*max_sf - offset)/sf_len;

@ -345,30 +345,38 @@ void nas::integrity_generate(uint8_t *key_128,
bool nas::integrity_check(byte_buffer_t *pdu) bool nas::integrity_check(byte_buffer_t *pdu)
{ {
uint8_t exp_mac[4]; if (!pdu) {
uint8_t *mac = &pdu->msg[1]; nas_log->error("Invalid PDU\n");
int i; return NULL;
}
if (pdu->N_bytes > 5) {
uint8_t exp_mac[4];
uint8_t *mac = &pdu->msg[1];
int i;
integrity_generate(&k_nas_int[16], integrity_generate(&k_nas_int[16],
ctxt.rx_count, ctxt.rx_count,
SECURITY_DIRECTION_DOWNLINK, SECURITY_DIRECTION_DOWNLINK,
&pdu->msg[5], &pdu->msg[5],
pdu->N_bytes-5, pdu->N_bytes-5,
&exp_mac[0]); &exp_mac[0]);
// Check if expected mac equals the sent mac // Check if expected mac equals the sent mac
for(i=0; i<4; i++){ for(i=0; i<4; i++){
if(exp_mac[i] != mac[i]){ if(exp_mac[i] != mac[i]){
nas_log->warning("Integrity check failure. Local: count=%d, [%02x %02x %02x %02x], " nas_log->warning("Integrity check failure. Local: count=%d, [%02x %02x %02x %02x], "
"Received: count=%d, [%02x %02x %02x %02x]\n", "Received: count=%d, [%02x %02x %02x %02x]\n",
ctxt.rx_count, exp_mac[0], exp_mac[1], exp_mac[2], exp_mac[3], ctxt.rx_count, exp_mac[0], exp_mac[1], exp_mac[2], exp_mac[3],
pdu->msg[5], mac[0], mac[1], mac[2], mac[3]); pdu->msg[5], mac[0], mac[1], mac[2], mac[3]);
return false; return false;
}
} }
nas_log->info("Integrity check ok. Local: count=%d, Received: count=%d\n",
ctxt.rx_count, pdu->msg[5]);
return true;
} else {
nas_log->error("Invalid integrity check PDU size (%d)\n", pdu->N_bytes);
} }
nas_log->info("Integrity check ok. Local: count=%d, Received: count=%d\n",
ctxt.rx_count, pdu->msg[5]);
return true;
} }
void nas::cipher_encrypt(byte_buffer_t *pdu) void nas::cipher_encrypt(byte_buffer_t *pdu)
@ -454,6 +462,17 @@ bool nas::check_cap_replay(LIBLTE_MME_UE_SECURITY_CAPABILITIES_STRUCT *caps)
******************************************************************************/ ******************************************************************************/
void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) { void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) {
if (!pdu) {
nas_log->error("Invalid PDU\n");
return;
}
if (pdu->N_bytes <= 5) {
nas_log->error("Invalid attach accept PDU size (%d)\n", pdu->N_bytes);
return;
}
LIBLTE_MME_ATTACH_ACCEPT_MSG_STRUCT attach_accept; LIBLTE_MME_ATTACH_ACCEPT_MSG_STRUCT attach_accept;
LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT act_def_eps_bearer_context_req; LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT act_def_eps_bearer_context_req;
LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_complete; LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_complete;
@ -679,6 +698,17 @@ void nas::parse_identity_request(uint32_t lcid, byte_buffer_t *pdu) {
void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu) void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu)
{ {
if (!pdu) {
nas_log->error("Invalid PDU\n");
return;
}
if (pdu->N_bytes <= 5) {
nas_log->error("Invalid security mode command PDU size (%d)\n", pdu->N_bytes);
return;
}
LIBLTE_MME_SECURITY_MODE_COMMAND_MSG_STRUCT sec_mode_cmd; LIBLTE_MME_SECURITY_MODE_COMMAND_MSG_STRUCT sec_mode_cmd;
LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sec_mode_comp; LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sec_mode_comp;
@ -808,6 +838,8 @@ void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *pdu) {
******************************************************************************/ ******************************************************************************/
void nas::send_attach_request() { void nas::send_attach_request() {
LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req; LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req;
byte_buffer_t *msg = pool_allocate; byte_buffer_t *msg = pool_allocate;
if (!msg) { if (!msg) {
@ -861,12 +893,16 @@ void nas::send_attach_request() {
(LIBLTE_BYTE_MSG_STRUCT *) msg); (LIBLTE_BYTE_MSG_STRUCT *) msg);
// Add MAC // Add MAC
integrity_generate(&k_nas_int[16], if (msg->N_bytes > 5) {
ctxt.tx_count, integrity_generate(&k_nas_int[16],
SECURITY_DIRECTION_UPLINK, ctxt.tx_count,
&msg->msg[5], SECURITY_DIRECTION_UPLINK,
msg->N_bytes - 5, &msg->msg[5],
&msg->msg[1]); msg->N_bytes - 5,
&msg->msg[1]);
} else {
nas_log->error("Invalid PDU size %d\n", msg->N_bytes);
}
} else { } else {
attach_req.eps_mobile_id.type_of_id = LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI; attach_req.eps_mobile_id.type_of_id = LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI;
usim->get_imsi_vec(attach_req.eps_mobile_id.imsi, 15); usim->get_imsi_vec(attach_req.eps_mobile_id.imsi, 15);

Loading…
Cancel
Save