Merge branch 'next' into epc

This commit is contained in:
Pedro Alvarez 2018-03-26 11:26:40 +01:00
commit 6e4720771f
11 changed files with 169 additions and 84 deletions

View File

@ -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")
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)
if (HAVE_AVX2)
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")
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")
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")
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 "Debug")
if (USE_LTE_RATES)
message(STATUS "Using standard LTE sampling rates")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFORCE_STANDARD_RATE")

View File

@ -32,10 +32,18 @@
extern "C" {
# endif
#ifdef NDEBUG
static char build_mode[] = "Release";
#ifdef BUILD_TYPE_RELEASE
static char build_mode[] = "Release";
#else
#ifdef BUILD_TYPE_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
// the configured build options for srsLTE

View File

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

View File

@ -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);
// 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
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__);;
// 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);

View File

@ -122,7 +122,7 @@ uint8_t* sch_pdu::write_packet(srslte::log *log_h)
sch_subh 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->console("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders);
return NULL;

View File

@ -100,8 +100,8 @@ public:
uint32_t get_ul_buffer(uint16_t rnti);
uint32_t get_dl_buffer(uint16_t rnti);
int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue);
int dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code);
int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue);
int dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code);
int dl_ant_info(uint16_t rnti, LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT *dedicated);
int dl_ack_info(uint32_t tti, uint16_t rnti, uint32_t tb_idx, bool ack);
@ -217,7 +217,7 @@ private:
bool configured;
pthread_mutex_t mutex;
pthread_mutex_t mutex, mutex2;
};

View File

@ -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
("sn_field_length", &rlc_cfg->sn_field_len,
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")) {
@ -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
("sn_field_length", &rlc_cfg->sn_field_len,
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
("t_reordering", &rlc_cfg->t_reordering,
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
@ -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
("t_poll_retx", &rlc_cfg->t_poll_retx,
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
("poll_pdu", &rlc_cfg->poll_pdu,
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
("poll_byte", &rlc_cfg->poll_byte,
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
("max_retx_thresh", &rlc_cfg->max_retx_thresh,
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")) {
@ -1124,12 +1138,16 @@ int field_qci::parse(libconfig::Setting &root)
parser::field_enum_num<LIBLTE_RRC_T_REORDERING_ENUM,int32> t_reordering
("t_reordering", &rlc_cfg->t_reordering,
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
("t_status_prohibit", &rlc_cfg->t_status_prohibit,
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;
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
("prioritized_bit_rate", &lc_cfg->prioritized_bit_rate,
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
("bucket_size_duration", &lc_cfg->bucket_size_duration,
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);
if (log_chan_group.parse(q["logical_channel_config"])) {

View File

@ -64,6 +64,7 @@ sched::sched() : bc_aggr_level(0), rar_aggr_level(0), avail_rbg(0), P(0), start_
}
pthread_mutex_init(&mutex, NULL);
pthread_mutex_init(&mutex2, NULL);
reset();
}
@ -71,6 +72,7 @@ sched::~sched()
{
srslte_regs_free(&regs);
pthread_mutex_destroy(&mutex);
pthread_mutex_destroy(&mutex2);
}
void sched::init(rrc_interface_mac *rrc_, srslte::log* log)
@ -173,13 +175,15 @@ int sched::ue_cfg(uint16_t rnti, sched_interface::ue_cfg_t *ue_cfg)
int sched::ue_rem(uint16_t rnti)
{
pthread_mutex_lock(&mutex);
int ret = 0;
pthread_mutex_lock(&mutex2);
int ret = 0;
if (ue_db.count(rnti)) {
ue_db.erase(rnti);
} else {
Error("User rnti=0x%x not found\n", rnti);
ret = -1;
}
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex);
return ret;
}
@ -217,13 +221,15 @@ int sched::bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bear
int sched::bearer_ue_rem(uint16_t rnti, uint32_t lc_id)
{
pthread_mutex_lock(&mutex);
int ret = 0;
pthread_mutex_lock(&mutex2);
int ret = 0;
if (ue_db.count(rnti)) {
ue_db[rnti].rem_bearer(lc_id);
} else {
Error("User rnti=0x%x not found\n", rnti);
ret = -1;
}
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex);
return ret;
}
@ -254,32 +260,42 @@ uint32_t sched::get_ul_buffer(uint16_t rnti)
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
*
* We add a new mutex used only in ue_rem to avoid the UE being removed in between the access to
* ue_db.count() and the access to the std::map.
*/
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;
if (ue_db.count(rnti)) {
pthread_mutex_lock(&mutex2);
int ret = 0;
if (ue_db.count(rnti)) {
ue_db[rnti].dl_buffer_state(lc_id, tx_queue, retx_queue);
} else {
Error("User rnti=0x%x not found\n", rnti);
ret = -1;
}
pthread_mutex_unlock(&mutex);
return ret;
pthread_mutex_unlock(&mutex2);
return ret;
}
/* \Warning Read comment in dl_rlc_buffer_state() */
int sched::dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code)
{
pthread_mutex_lock(&mutex);
int ret = 0;
pthread_mutex_lock(&mutex2);
int ret = 0;
if (ue_db.count(rnti)) {
ue_db[rnti].mac_buffer_state(ce_code);
} else {
Error("User rnti=0x%x not found\n", rnti);
ret = -1;
}
pthread_mutex_unlock(&mutex);
return ret;
pthread_mutex_unlock(&mutex2);
return ret;
}
int sched::dl_ant_info(uint16_t rnti, LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT *dl_ant_info) {
@ -676,10 +692,11 @@ int sched::dl_sched_data(dl_sched_data_t data[MAX_DATA_LIST])
int nof_data_elems = 0;
for(std::map<uint16_t, sched_ue>::iterator iter=ue_db.begin(); iter!=ue_db.end(); ++iter) {
sched_ue *user = (sched_ue*) &iter->second;
uint16_t rnti = (uint16_t) iter->first;
sched_ue *user = (sched_ue*) &iter->second;
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();
data[nof_data_elems].dci_format = dci_format;
@ -706,10 +723,12 @@ int sched::dl_sched_data(dl_sched_data_t data[MAX_DATA_LIST])
Error("DCI format (%d) not implemented\n", dci_format);
}
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(),
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");
nof_data_elems++;
} else {

View File

@ -148,9 +148,7 @@ dl_harq_proc* dl_metric_rr::get_user_allocation(sched_ue *user)
if (pending_data || (h && !h->is_empty())) {
#endif
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;
}
}

View File

@ -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;
#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;

View File

@ -345,30 +345,38 @@ void nas::integrity_generate(uint8_t *key_128,
bool nas::integrity_check(byte_buffer_t *pdu)
{
uint8_t exp_mac[4];
uint8_t *mac = &pdu->msg[1];
int i;
integrity_generate(&k_nas_int[16],
ctxt.rx_count,
SECURITY_DIRECTION_DOWNLINK,
&pdu->msg[5],
pdu->N_bytes-5,
&exp_mac[0]);
// Check if expected mac equals the sent mac
for(i=0; i<4; i++){
if(exp_mac[i] != mac[i]){
nas_log->warning("Integrity check failure. Local: count=%d, [%02x %02x %02x %02x], "
"Received: count=%d, [%02x %02x %02x %02x]\n",
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]);
return false;
}
if (!pdu) {
nas_log->error("Invalid PDU\n");
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],
ctxt.rx_count,
SECURITY_DIRECTION_DOWNLINK,
&pdu->msg[5],
pdu->N_bytes-5,
&exp_mac[0]);
// Check if expected mac equals the sent mac
for(i=0; i<4; i++){
if(exp_mac[i] != mac[i]){
nas_log->warning("Integrity check failure. Local: count=%d, [%02x %02x %02x %02x], "
"Received: count=%d, [%02x %02x %02x %02x]\n",
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]);
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)
@ -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) {
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_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT act_def_eps_bearer_context_req;
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)
{
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_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() {
LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req;
byte_buffer_t *msg = pool_allocate;
if (!msg) {
@ -861,12 +893,16 @@ void nas::send_attach_request() {
(LIBLTE_BYTE_MSG_STRUCT *) msg);
// Add MAC
integrity_generate(&k_nas_int[16],
ctxt.tx_count,
SECURITY_DIRECTION_UPLINK,
&msg->msg[5],
msg->N_bytes - 5,
&msg->msg[1]);
if (msg->N_bytes > 5) {
integrity_generate(&k_nas_int[16],
ctxt.tx_count,
SECURITY_DIRECTION_UPLINK,
&msg->msg[5],
msg->N_bytes - 5,
&msg->msg[1]);
} else {
nas_log->error("Invalid PDU size %d\n", msg->N_bytes);
}
} else {
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);