From 1aced47d6a833a6a25cafd8878e6ee63ef016a0d Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Sun, 28 Jan 2018 12:01:58 +0100 Subject: [PATCH 01/46] Making the SQN readable from the csv database file --- srsepc/hdr/hss/hss.h | 5 ++--- srsepc/src/hss/hss.cc | 31 ++++++++++--------------------- srsepc/user_db.csv.example | 7 ++++--- 3 files changed, 16 insertions(+), 27 deletions(-) diff --git a/srsepc/hdr/hss/hss.h b/srsepc/hdr/hss/hss.h index 25863b7eb..9e30f8d1b 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -56,6 +56,7 @@ typedef struct{ uint8_t key[16]; uint8_t op[16]; uint8_t amf[2]; + uint8_t sqn[6]; }hss_ue_ctx_t; enum hss_auth_algo { @@ -74,9 +75,8 @@ public: bool set_auth_algo(std::string auth_algo); bool read_db_file(std::string db_file); - void get_sqn(uint8_t sqn[6]); void gen_rand(uint8_t rand_[16]); - bool get_k_amf_op(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *op); + bool get_k_amf_op_sqn(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *op, uint8_t *sqn); bool gen_auth_info_answer(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres); bool gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres); bool gen_auth_info_answer_xor(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres); @@ -90,7 +90,6 @@ private: virtual ~hss(); static hss *m_instance; - uint64_t m_sqn; //48 bits srslte::byte_buffer_pool *m_pool; std::ifstream m_db_file; diff --git a/srsepc/src/hss/hss.cc b/srsepc/src/hss/hss.cc index debd6bd50..7211788d6 100644 --- a/srsepc/src/hss/hss.cc +++ b/srsepc/src/hss/hss.cc @@ -39,8 +39,6 @@ hss* hss::m_instance = NULL; boost::mutex hss_instance_mutex; hss::hss() -// :m_sqn(0x112233445566) - :m_sqn(0) { m_pool = srslte::byte_buffer_pool::get_instance(); return; @@ -152,7 +150,7 @@ hss::read_db_file(std::string db_filename) if(line[0] != '#') { std::vector split = split_string(line,','); - if(split.size()!=5) + if(split.size()!=6) { m_hss_log->error("Error parsing UE database\n"); return false; @@ -163,11 +161,13 @@ hss::read_db_file(std::string db_filename) get_uint_vec_from_hex_str(split[2],ue_ctx->key,16); get_uint_vec_from_hex_str(split[3],ue_ctx->op,16); get_uint_vec_from_hex_str(split[4],ue_ctx->amf,2); + get_uint_vec_from_hex_str(split[5],ue_ctx->sqn,6); m_hss_log->debug("Added user from DB, IMSI: %015lu\n", ue_ctx->imsi); m_hss_log->debug_hex(ue_ctx->key, 16, "User Key : "); m_hss_log->debug_hex(ue_ctx->op, 16, "User OP : "); m_hss_log->debug_hex(ue_ctx->amf, 2, "AMF : "); + m_hss_log->debug_hex(ue_ctx->sqn, 6, "SQN : "); m_imsi_to_ue_ctx.insert(std::pair(ue_ctx->imsi,ue_ctx)); } @@ -207,12 +207,11 @@ hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn uint8_t mac[8]; - if(!get_k_amf_op(imsi,k,amf,op)) + if(!get_k_amf_op_sqn(imsi, k, amf, op, sqn)) { return false; } gen_rand(rand); - get_sqn(sqn); security_milenage_f2345( k, op, @@ -289,12 +288,11 @@ hss::gen_auth_info_answer_xor(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uin int i = 0; - if(!get_k_amf_op(imsi,k,amf,op)) + if(!get_k_amf_op_sqn(imsi, k, amf, op, sqn)) { return false; } gen_rand(rand); - get_sqn(sqn); // Use RAND and K to compute RES, CK, IK and AK for(i=0; i<16; i++) { @@ -381,7 +379,7 @@ hss::gen_auth_info_answer_xor(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uin bool -hss::get_k_amf_op(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *op ) +hss::get_k_amf_op_sqn(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *op, uint8_t *sqn) { /* @@ -398,23 +396,14 @@ hss::get_k_amf_op(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *op ) } hss_ue_ctx_t *ue_ctx = ue_ctx_it->second; m_hss_log->info("Found User %015lu\n",imsi); - memcpy(k,ue_ctx->key,16); - memcpy(amf,ue_ctx->amf,2); - memcpy(op,ue_ctx->op,16); + memcpy(k, ue_ctx->key, 16); + memcpy(amf, ue_ctx->amf, 2); + memcpy(op, ue_ctx->op, 16); + memcpy(sqn, ue_ctx->sqn, 6); return true; } -void -hss::get_sqn(uint8_t sqn[6]) -{ - for (int i=0; i<6; i++) - { - sqn[i] = ((uint8_t *)&m_sqn)[i]; - } - m_sqn++; - return; //TODO See TS 33.102, Annex C -} void hss::gen_rand(uint8_t rand_[16]) diff --git a/srsepc/user_db.csv.example b/srsepc/user_db.csv.example index 89d0dedf1..6f500e928 100644 --- a/srsepc/user_db.csv.example +++ b/srsepc/user_db.csv.example @@ -6,8 +6,9 @@ # IMSI: UE's IMSI value # Key: UE's key, where other keys are derived from. Stored in hexadecimal # OP: Operator's code, sotred in hexadecimal -# AMF: Authentication management feild, stored in hexadecimal +# AMF: Authentication management field, stored in hexadecimal +# SQN: UE's Sequence number for freshness of the authentication # # Note: Lines starting by '#' are ignored -ue1,001010123456789,00112233445566778899aabbccddeeff,63BFA50EE6523365FF14C1F45F88737D,9001 -ue2,001010123456780,00112233445566778899aabbccddeeaa,63BFA50EE6523365FF14C1F45F88737D,2000 +ue1,001010123456789,00112233445566778899aabbccddeeff,63BFA50EE6523365FF14C1F45F88737D,9001,000000001234 +ue2,001010123456780,00112233445566778899aabbccddeeaa,63BFA50EE6523365FF14C1F45F88737D,2000,000000001235 From 2835ec4124b8705b6bd92e662a6564fa4c2eea9e Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Sun, 28 Jan 2018 12:03:36 +0100 Subject: [PATCH 02/46] Add description for algo in example file --- srsepc/epc.conf.example | 1 + 1 file changed, 1 insertion(+) diff --git a/srsepc/epc.conf.example b/srsepc/epc.conf.example index 739b2c137..d90e3a6ef 100644 --- a/srsepc/epc.conf.example +++ b/srsepc/epc.conf.example @@ -24,6 +24,7 @@ mme_bind_addr = 127.0.1.100 ##################################################################### # HSS configuration # +# algo: Authentication algorithm (xor/milenage) # db_file: Location of .csv file that stores UEs information. # ##################################################################### From 7476b2f89609b2a10a5c1f5282a371b89dc19037 Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Sun, 28 Jan 2018 12:08:35 +0100 Subject: [PATCH 03/46] Beautiful IMSI output --- srsepc/src/hss/hss.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsepc/src/hss/hss.cc b/srsepc/src/hss/hss.cc index 7211788d6..776c7d013 100644 --- a/srsepc/src/hss/hss.cc +++ b/srsepc/src/hss/hss.cc @@ -102,8 +102,8 @@ hss::stop(void) std::map::iterator it = m_imsi_to_ue_ctx.begin(); while(it!=m_imsi_to_ue_ctx.end()) { - m_hss_log->info("Deleting UE context in HSS. IMSI: %lu\n", it->second->imsi); - m_hss_log->console("Deleting UE context in HSS. IMSI: %lu\n", it->second->imsi); + m_hss_log->info("Deleting UE context in HSS. IMSI: %015lu\n", it->second->imsi); + m_hss_log->console("Deleting UE context in HSS. IMSI: %015lu\n", it->second->imsi); delete it->second; m_imsi_to_ue_ctx.erase(it++); } From 5666d3021dc07bfb165a68974323aa97004ee701 Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Sun, 28 Jan 2018 13:22:59 +0100 Subject: [PATCH 04/46] Write sqn and user context back to db file --- srsepc/hdr/hss/hss.h | 12 ++++---- srsepc/src/hss/hss.cc | 69 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 9 deletions(-) diff --git a/srsepc/hdr/hss/hss.h b/srsepc/hdr/hss/hss.h index 9e30f8d1b..d80f0441f 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -72,9 +72,6 @@ public: int init(hss_args_t *hss_args, srslte::log_filter* hss_log); void stop(void); - bool set_auth_algo(std::string auth_algo); - bool read_db_file(std::string db_file); - void gen_rand(uint8_t rand_[16]); bool get_k_amf_op_sqn(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *op, uint8_t *sqn); bool gen_auth_info_answer(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres); @@ -91,12 +88,17 @@ private: static hss *m_instance; srslte::byte_buffer_pool *m_pool; - std::ifstream m_db_file; std::map m_imsi_to_ue_ctx; - enum hss_auth_algo m_auth_algo; + bool set_auth_algo(std::string auth_algo); + bool read_db_file(std::string db_file); + bool write_db_file(std::string db_file); + + std::string hex_string(uint8_t *hex, int size); + enum hss_auth_algo m_auth_algo; + std::string db_file; /*Logs*/ srslte::log_filter *m_hss_log; diff --git a/srsepc/src/hss/hss.cc b/srsepc/src/hss/hss.cc index 776c7d013..ef8bfcfd4 100644 --- a/srsepc/src/hss/hss.cc +++ b/srsepc/src/hss/hss.cc @@ -27,6 +27,7 @@ #include /* time */ #include #include +#include #include #include "hss/hss.h" #include "srslte/common/security.h" @@ -90,6 +91,8 @@ hss::init(hss_args_t *hss_args, srslte::log_filter *hss_log) mcc = hss_args->mcc; mnc = hss_args->mnc; + + db_file = hss_args->db_file; m_hss_log->info("HSS Initialized. DB file %s, authentication algorithm %s, MCC: %d, MNC: %d\n", hss_args->db_file.c_str(),hss_args->auth_algo.c_str(), mcc, mnc); m_hss_log->console("HSS Initialized\n"); @@ -99,6 +102,7 @@ hss::init(hss_args_t *hss_args, srslte::log_filter *hss_log) void hss::stop(void) { + write_db_file(db_file); std::map::iterator it = m_imsi_to_ue_ctx.begin(); while(it!=m_imsi_to_ue_ctx.end()) { @@ -107,10 +111,6 @@ hss::stop(void) delete it->second; m_imsi_to_ue_ctx.erase(it++); } - if(m_db_file.is_open()) - { - m_db_file.close(); - } return; } @@ -137,6 +137,8 @@ hss::set_auth_algo(std::string auth_algo) bool hss::read_db_file(std::string db_filename) { + std::ifstream m_db_file; + m_db_file.open(db_filename.c_str(), std::ifstream::in); if(!m_db_file.is_open()) { @@ -173,6 +175,53 @@ hss::read_db_file(std::string db_filename) } } + if(m_db_file.is_open()) + { + m_db_file.close(); + } + + return true; +} + +bool hss::write_db_file(std::string db_filename) +{ + std::string line; + uint8_t k[16]; + uint8_t amf[2]; + uint8_t op[16]; + uint8_t sqn[6]; + + std::ofstream m_db_file; + + m_db_file.open(db_filename.c_str(), std::ofstream::out); + if(!m_db_file.is_open()) + { + return false; + } + m_hss_log->info("Opened DB file: %s\n", db_filename.c_str() ); + + std::map::iterator it = m_imsi_to_ue_ctx.begin(); + while(it!=m_imsi_to_ue_ctx.end()) + { + m_db_file << it->second->name; + m_db_file << ","; + m_db_file << std::setfill('0') << std::setw(15) << it->second->imsi; + m_db_file << ","; + m_db_file << hex_string(it->second->key, 16); + m_db_file << ","; + m_db_file << hex_string(it->second->op, 16); + m_db_file << ","; + m_db_file << hex_string(it->second->amf, 2); + m_db_file << ","; + m_db_file << hex_string(it->second->sqn, 6); + m_db_file << std::endl; + it++; + } + + if(m_db_file.is_open()) + { + m_db_file.close(); + } return true; } @@ -443,6 +492,18 @@ hss::get_uint_vec_from_hex_str(const std::string &key_str, uint8_t *key, uint le return; } + +std::string +hss::hex_string(uint8_t *hex, int size) +{ + std::stringstream ss; + + ss << std::hex << std::setfill('0'); + for(int i=0;i(hex[i]); + } + return ss.str(); +} /* uint64_t string_to_imsi() From 9f5affb6c790fe7ac7a3a543eaa8973f4baef6a5 Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Sun, 28 Jan 2018 13:24:26 +0100 Subject: [PATCH 05/46] Clean up file --- srsepc/src/hss/hss.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/srsepc/src/hss/hss.cc b/srsepc/src/hss/hss.cc index ef8bfcfd4..948c6752a 100644 --- a/srsepc/src/hss/hss.cc +++ b/srsepc/src/hss/hss.cc @@ -431,11 +431,6 @@ bool hss::get_k_amf_op_sqn(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *op, uint8_t *sqn) { - /* - uint8_t k_tmp[16] ={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff}; - uint8_t amf_tmp[2]={0x80,0x00}; - uint8_t op_tmp[16]={0x63,0xbf,0xA5,0x0E,0xE6,0x52,0x33,0x65,0xFF,0x14,0xC1,0xF4,0x5F,0x88,0x73,0x7D}; - */ std::map::iterator ue_ctx_it = m_imsi_to_ue_ctx.find(imsi); if(ue_ctx_it == m_imsi_to_ue_ctx.end()) { From 9f3d14cfabad06bfb0caa730980418f7e1d8f475 Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Sun, 28 Jan 2018 14:49:53 +0100 Subject: [PATCH 06/46] Increment sqn --- srsepc/hdr/hss/hss.h | 2 ++ srsepc/src/hss/hss.cc | 30 +++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/srsepc/hdr/hss/hss.h b/srsepc/hdr/hss/hss.h index d80f0441f..0f05a02bb 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -91,6 +91,8 @@ private: std::map m_imsi_to_ue_ctx; + void increment_sqn(uint64_t imsi); + bool set_auth_algo(std::string auth_algo); bool read_db_file(std::string db_file); bool write_db_file(std::string db_file); diff --git a/srsepc/src/hss/hss.cc b/srsepc/src/hss/hss.cc index 948c6752a..0dd5bec9b 100644 --- a/srsepc/src/hss/hss.cc +++ b/srsepc/src/hss/hss.cc @@ -95,7 +95,7 @@ hss::init(hss_args_t *hss_args, srslte::log_filter *hss_log) db_file = hss_args->db_file; m_hss_log->info("HSS Initialized. DB file %s, authentication algorithm %s, MCC: %d, MNC: %d\n", hss_args->db_file.c_str(),hss_args->auth_algo.c_str(), mcc, mnc); - m_hss_log->console("HSS Initialized\n"); + m_hss_log->console("HSS Initialized.\n"); return 0; } @@ -238,6 +238,7 @@ hss::gen_auth_info_answer(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t ret = gen_auth_info_answer_milenage(imsi, k_asme, autn, rand, xres); break; } + increment_sqn(imsi); return ret; } @@ -448,6 +449,33 @@ hss::get_k_amf_op_sqn(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *op, uint return true; } +void +hss::increment_sqn(uint64_t imsi) +{ + std::map::iterator ue_ctx_it = m_imsi_to_ue_ctx.find(imsi); + if(ue_ctx_it == m_imsi_to_ue_ctx.end()) + { + m_hss_log->info("User not found. IMSI: %015lu\n",imsi); + } + + hss_ue_ctx_t *ue_ctx = ue_ctx_it->second; + + // Awkward 48 bit sqn and doing arithmetic + uint64_t sqn = 0; + uint8_t *p = (uint8_t *)&sqn; + + for(int i = 0; i < 6; i++) { + p[5-i] = (uint8_t) ((ue_ctx_it->second->sqn[i])); + } + + sqn++; + + m_hss_log->debug("Incremented IMSI: %015lu SQN: %d", imsi, sqn); + + for(int i = 0; i < 6; i++){ + ue_ctx_it->second->sqn[i] = p[5-i]; + } +} void hss::gen_rand(uint8_t rand_[16]) From 53f05354e658145dc3958f645dcddeb4b1618974 Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Sun, 28 Jan 2018 16:39:23 +0100 Subject: [PATCH 07/46] Making HSS functions private --- srsepc/hdr/hss/hss.h | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/srsepc/hdr/hss/hss.h b/srsepc/hdr/hss/hss.h index 0f05a02bb..34cd71b7c 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -72,14 +72,8 @@ public: int init(hss_args_t *hss_args, srslte::log_filter* hss_log); void stop(void); - void gen_rand(uint8_t rand_[16]); - bool get_k_amf_op_sqn(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *op, uint8_t *sqn); bool gen_auth_info_answer(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres); - bool gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres); - bool gen_auth_info_answer_xor(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres); - std::vector split_string(const std::string &str, char delimiter); - void get_uint_vec_from_hex_str(const std::string &key_str, uint8_t *key, uint len); private: @@ -91,6 +85,16 @@ private: std::map m_imsi_to_ue_ctx; + + void gen_rand(uint8_t rand_[16]); + bool get_k_amf_op_sqn(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *op, uint8_t *sqn); + + bool gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres); + bool gen_auth_info_answer_xor(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres); + + std::vector split_string(const std::string &str, char delimiter); + void get_uint_vec_from_hex_str(const std::string &key_str, uint8_t *key, uint len); + void increment_sqn(uint64_t imsi); bool set_auth_algo(std::string auth_algo); From 3ead643c647b839ac7e6d7eba563a19be28a0206 Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Sun, 28 Jan 2018 16:46:35 +0100 Subject: [PATCH 08/46] Introducing epc interfaces for hss and srsepc namespace --- lib/include/srslte/interfaces/epc_interfaces.h | 17 +++++++++++++++++ srsepc/hdr/hss/hss.h | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 lib/include/srslte/interfaces/epc_interfaces.h diff --git a/lib/include/srslte/interfaces/epc_interfaces.h b/lib/include/srslte/interfaces/epc_interfaces.h new file mode 100644 index 000000000..09377878d --- /dev/null +++ b/lib/include/srslte/interfaces/epc_interfaces.h @@ -0,0 +1,17 @@ +#ifndef EPC_INTERFACE_H +#define EPC_INTERFACE_H + +#include "srslte/srslte.h" + +#include "srslte/common/common.h" + +namespace srsepc { + +class hss_interface_s1ap +{ +public: + virtual bool gen_auth_info_answer(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres) = 0; +}; + +} +#endif // ENB_METRICS_INTERFACE_H diff --git a/srsepc/hdr/hss/hss.h b/srsepc/hdr/hss/hss.h index 34cd71b7c..7cafe21ce 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -38,6 +38,7 @@ #include "srslte/common/logger_file.h" #include "srslte/common/log_filter.h" #include "srslte/common/buffer_pool.h" +#include "srslte/interfaces/epc_interfaces.h" #include #include @@ -64,7 +65,7 @@ enum hss_auth_algo { HSS_ALGO_MILENAGE }; -class hss +class hss : public srsepc::hss_interface_s1ap { public: static hss* get_instance(void); From 8ea2e73b633302a9701bea7017bd6baded4e407d Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Sun, 28 Jan 2018 16:56:39 +0100 Subject: [PATCH 09/46] Making hss an interface for testing --- srsepc/hdr/hss/hss.h | 2 +- srsepc/hdr/mme/mme.h | 2 +- srsepc/hdr/mme/s1ap.h | 4 ++-- srsepc/hdr/mme/s1ap_nas_transport.h | 4 ++-- srsepc/src/main.cc | 15 ++++++++------- srsepc/src/mme/mme.cc | 4 ++-- srsepc/src/mme/s1ap.cc | 10 +++++----- srsepc/src/mme/s1ap_nas_transport.cc | 4 ++-- 8 files changed, 23 insertions(+), 22 deletions(-) diff --git a/srsepc/hdr/hss/hss.h b/srsepc/hdr/hss/hss.h index 7cafe21ce..2adc71545 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -65,7 +65,7 @@ enum hss_auth_algo { HSS_ALGO_MILENAGE }; -class hss : public srsepc::hss_interface_s1ap +class hss : public hss_interface_s1ap { public: static hss* get_instance(void); diff --git a/srsepc/hdr/mme/mme.h b/srsepc/hdr/mme/mme.h index 26296c2c6..c0eac0685 100644 --- a/srsepc/hdr/mme/mme.h +++ b/srsepc/hdr/mme/mme.h @@ -66,7 +66,7 @@ class mme: public: static mme* get_instance(void); static void cleanup(void); - int init(mme_args_t* args, srslte::log_filter *s1ap_log, srslte::log_filter *mme_gtpc_log); + int init(mme_args_t* args, srslte::log_filter *s1ap_log, srslte::log_filter *mme_gtpc_log, hss_interface_s1ap * hss_); void stop(); int get_s1_mme(); void run_thread(); diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index fc4dd3d49..963e8d51f 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -59,7 +59,7 @@ public: static void cleanup(); int enb_listen(); - int init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log); + int init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log, hss_interface_s1ap * hss_); void stop(); int get_s1_mme(); @@ -103,7 +103,7 @@ private: uint32_t m_plmn; srslte::byte_buffer_pool *m_pool; - hss *m_hss; + hss_interface_s1ap *m_hss; int m_s1mme; std::map m_active_enbs; std::map m_sctp_to_enb_id; diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index e37ce4d61..2e9a1a9a7 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -42,7 +42,7 @@ public: static s1ap_nas_transport* m_instance; static s1ap_nas_transport* get_instance(void); static void cleanup(void); - void init(void); + void init(hss_interface_s1ap * hss_); bool handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSAGE_STRUCT *init_ue, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); bool handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRANSPORT_STRUCT *ul_xport, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); @@ -97,7 +97,7 @@ private: srslte::byte_buffer_pool *m_pool; s1ap* m_s1ap; - hss* m_hss; + hss_interface_s1ap* m_hss; mme_gtpc* m_mme_gtpc; }; diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index 8e9db9259..365bcbf17 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -304,19 +304,20 @@ main (int argc,char * argv[] ) spgw_log.init("SPGW",logger); spgw_log.set_level(level(args.log_args.spgw_level)); spgw_log.set_hex_limit(args.log_args.spgw_hex_limit); - - mme *mme = mme::get_instance(); - if (mme->init(&args.mme_args, &s1ap_log, &mme_gtpc_log)) { - cout << "Error initializing MME" << endl; - exit(1); - } + hss *hss = hss::get_instance(); if (hss->init(&args.hss_args,&hss_log)) { cout << "Error initializing HSS" << endl; exit(1); } - + + mme *mme = mme::get_instance(); + if (mme->init(&args.mme_args, &s1ap_log, &mme_gtpc_log, hss)) { + cout << "Error initializing MME" << endl; + exit(1); + } + spgw *spgw = spgw::get_instance(); if (spgw->init(&args.spgw_args,&spgw_log)) { cout << "Error initializing SP-GW" << endl; diff --git a/srsepc/src/mme/mme.cc b/srsepc/src/mme/mme.cc index ab4778c20..eb247164c 100644 --- a/srsepc/src/mme/mme.cc +++ b/srsepc/src/mme/mme.cc @@ -70,7 +70,7 @@ mme::cleanup(void) } int -mme::init(mme_args_t* args, srslte::log_filter *s1ap_log, srslte::log_filter *mme_gtpc_log) +mme::init(mme_args_t* args, srslte::log_filter *s1ap_log, srslte::log_filter *mme_gtpc_log, hss_interface_s1ap * hss_) { /*Init logger*/ @@ -78,7 +78,7 @@ mme::init(mme_args_t* args, srslte::log_filter *s1ap_log, srslte::log_filter *mm m_mme_gtpc_log = mme_gtpc_log; /*Init S1AP*/ m_s1ap = s1ap::get_instance(); - if(m_s1ap->init(args->s1ap_args, s1ap_log)){ + if(m_s1ap->init(args->s1ap_args, s1ap_log, hss_)){ m_s1ap_log->error("Error initializing MME S1APP\n"); exit(-1); } diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 07563e7ca..0d975ca61 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -67,7 +67,7 @@ s1ap::cleanup(void) } int -s1ap::init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log) +s1ap::init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log, hss_interface_s1ap * hss_) { m_pool = srslte::byte_buffer_pool::get_instance(); @@ -77,18 +77,18 @@ s1ap::init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log) //Init log m_s1ap_log = s1ap_log; + //Get pointer to the HSS + m_hss = hss_; + //Init message handlers m_s1ap_mngmt_proc = s1ap_mngmt_proc::get_instance(); //Managment procedures m_s1ap_mngmt_proc->init(); m_s1ap_nas_transport = s1ap_nas_transport::get_instance(); //NAS Transport procedures - m_s1ap_nas_transport->init(); + m_s1ap_nas_transport->init(m_hss); m_s1ap_ctx_mngmt_proc = s1ap_ctx_mngmt_proc::get_instance(); //Context Management Procedures m_s1ap_ctx_mngmt_proc->init(); - //Get pointer to the HSS - m_hss = hss::get_instance(); - //Get pointer to GTP-C class m_mme_gtpc = mme_gtpc::get_instance(); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 092e92ae3..5aab70f16 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -64,13 +64,13 @@ s1ap_nas_transport::cleanup(void) } void -s1ap_nas_transport::init(void) +s1ap_nas_transport::init(hss_interface_s1ap * hss_) { m_s1ap = s1ap::get_instance(); m_s1ap_log = m_s1ap->m_s1ap_log; m_pool = srslte::byte_buffer_pool::get_instance(); - m_hss = hss::get_instance(); + m_hss = hss_; m_mme_gtpc = mme_gtpc::get_instance(); } From 5db5399b2f3776002c4f0b558e10d9609b461006 Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Mon, 29 Jan 2018 13:22:48 +0100 Subject: [PATCH 10/46] Added HSS sync support (not tested) --- .../srslte/interfaces/epc_interfaces.h | 1 + srsepc/hdr/hss/hss.h | 11 +- srsepc/src/hss/hss.cc | 156 +++++++++++++++++- 3 files changed, 159 insertions(+), 9 deletions(-) diff --git a/lib/include/srslte/interfaces/epc_interfaces.h b/lib/include/srslte/interfaces/epc_interfaces.h index 09377878d..21646628a 100644 --- a/lib/include/srslte/interfaces/epc_interfaces.h +++ b/lib/include/srslte/interfaces/epc_interfaces.h @@ -11,6 +11,7 @@ class hss_interface_s1ap { public: virtual bool gen_auth_info_answer(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres) = 0; + virtual bool resync_sqn(uint64_t imsi, uint8_t *auts) = 0; }; } diff --git a/srsepc/hdr/hss/hss.h b/srsepc/hdr/hss/hss.h index 2adc71545..6abd91a57 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -58,6 +58,7 @@ typedef struct{ uint8_t op[16]; uint8_t amf[2]; uint8_t sqn[6]; + uint8_t last_rand[16]; }hss_ue_ctx_t; enum hss_auth_algo { @@ -74,7 +75,7 @@ public: void stop(void); bool gen_auth_info_answer(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres); - + bool resync_sqn(uint64_t imsi, uint8_t *auts); private: @@ -93,14 +94,22 @@ private: bool gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres); bool gen_auth_info_answer_xor(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres); + bool resync_sqn_milenage(uint64_t imsi, uint8_t *auts); + bool resync_sqn_xor(uint64_t imsi, uint8_t *auts); + std::vector split_string(const std::string &str, char delimiter); void get_uint_vec_from_hex_str(const std::string &key_str, uint8_t *key, uint len); void increment_sqn(uint64_t imsi); + void set_sqn(uint64_t imsi, uint8_t *sqn); + + void set_last_rand(uint64_t imsi, uint8_t *rand); + void get_last_rand(uint64_t imsi, uint8_t *rand); bool set_auth_algo(std::string auth_algo); bool read_db_file(std::string db_file); bool write_db_file(std::string db_file); + bool get_ue_ctx(uint64_t imsi, hss_ue_ctx_t *ue_ctx); std::string hex_string(uint8_t *hex, int size); diff --git a/srsepc/src/hss/hss.cc b/srsepc/src/hss/hss.cc index 0dd5bec9b..30cc2571b 100644 --- a/srsepc/src/hss/hss.cc +++ b/srsepc/src/hss/hss.cc @@ -243,6 +243,93 @@ hss::gen_auth_info_answer(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t } +bool +hss::resync_sqn(uint64_t imsi, uint8_t *auts) +{ + bool ret = false; + switch (m_auth_algo) + { + case HSS_ALGO_XOR: + ret = resync_sqn_xor(imsi, auts); + break; + case HSS_ALGO_MILENAGE: + ret = resync_sqn_milenage(imsi, auts); + break; + } + return ret; +} + +bool +hss::resync_sqn_xor(uint64_t imsi, uint8_t *auts) +{ + m_hss_log->error("XOR SQN synchronization not supported yet\n"); + m_hss_log->console("XOR SQNs synchronization not supported yet\n"); + return false; +} + + +bool +hss::resync_sqn_milenage(uint64_t imsi, uint8_t *auts) +{ + uint8_t last_rand[16]; + uint8_t ak[6]; + uint8_t mac_s[8]; + uint8_t sqn_ms_xor_ak[6]; + + uint8_t k[16]; + uint8_t amf[2]; + uint8_t op[16]; + uint8_t sqn[6]; + + if(!get_k_amf_op_sqn(imsi, k, amf, op, sqn)) + { + return false; + } + + get_last_rand(imsi, last_rand); + + for(int i=0; i<6; i++){ + sqn_ms_xor_ak[i] = auts[i]; + } + + for(int i=0; i<8; i++){ + mac_s[i] = auts[i+6]; + } + + m_hss_log->debug_hex(k, 16, "User Key : "); + m_hss_log->debug_hex(op, 16, "User OP : "); + m_hss_log->debug_hex(last_rand, 16, "User Last Rand : "); + m_hss_log->debug_hex(auts, 16, "AUTS : "); + m_hss_log->debug_hex(sqn_ms_xor_ak, 6, "SQN xor AK : "); + m_hss_log->debug_hex(mac_s, 8, "MAC : "); + + security_milenage_f5_star(k, op, last_rand, ak); + m_hss_log->debug_hex(ak, 6, "Resynch AK : "); + + uint8_t sqn_ms[6]; + for(int i=0; i<6; i++){ + sqn_ms[i] = sqn_ms_xor_ak[i] ^ ak[i]; + } + m_hss_log->debug_hex(sqn_ms, 6, "SQN MS : "); + + uint8_t mac_s_tmp[8]; + + security_milenage_f1_star(k, op, last_rand, sqn_ms, amf, mac_s_tmp); + + m_hss_log->debug_hex(mac_s_tmp, 8, "MAC calc : "); + + for(int i=0; i<8; i++){ + if(!(mac_s_tmp[i] == mac_s[i])){ + m_hss_log->error("Calculated MAC does not match sent MAC\n"); + return false; + } + } + + set_sqn(imsi, sqn_ms); + + return true; +} + bool hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres) { @@ -262,7 +349,7 @@ hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn return false; } gen_rand(rand); - + security_milenage_f2345( k, op, rand, @@ -317,6 +404,8 @@ hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn m_hss_log->debug_hex(autn, 16, "User AUTN: "); + set_last_rand(imsi, rand); + return true; } @@ -424,6 +513,8 @@ hss::gen_auth_info_answer_xor(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uin m_hss_log->debug_hex(autn, 8, "User AUTN: "); + set_last_rand(imsi, rand); + return true; } @@ -452,20 +543,19 @@ hss::get_k_amf_op_sqn(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *op, uint void hss::increment_sqn(uint64_t imsi) { - std::map::iterator ue_ctx_it = m_imsi_to_ue_ctx.find(imsi); - if(ue_ctx_it == m_imsi_to_ue_ctx.end()) + hss_ue_ctx_t *ue_ctx = NULL; + bool ret = get_ue_ctx(imsi, ue_ctx); + if(ret == false) { - m_hss_log->info("User not found. IMSI: %015lu\n",imsi); + return; } - - hss_ue_ctx_t *ue_ctx = ue_ctx_it->second; // Awkward 48 bit sqn and doing arithmetic uint64_t sqn = 0; uint8_t *p = (uint8_t *)&sqn; for(int i = 0; i < 6; i++) { - p[5-i] = (uint8_t) ((ue_ctx_it->second->sqn[i])); + p[5-i] = (uint8_t) ((ue_ctx->sqn[i])); } sqn++; @@ -473,10 +563,47 @@ hss::increment_sqn(uint64_t imsi) m_hss_log->debug("Incremented IMSI: %015lu SQN: %d", imsi, sqn); for(int i = 0; i < 6; i++){ - ue_ctx_it->second->sqn[i] = p[5-i]; + ue_ctx->sqn[i] = p[5-i]; } } +void +hss::set_sqn(uint64_t imsi, uint8_t *sqn) +{ + hss_ue_ctx_t *ue_ctx = NULL; + bool ret = get_ue_ctx(imsi, ue_ctx); + if(ret == false) + { + return; + } + memcpy(ue_ctx->sqn, sqn, 6); +} + +void +hss::set_last_rand(uint64_t imsi, uint8_t *rand) +{ + hss_ue_ctx_t *ue_ctx = NULL; + bool ret = get_ue_ctx(imsi, ue_ctx); + if(ret == false) + { + return; + } + memcpy(ue_ctx->last_rand, rand, 16); + +} + +void +hss::get_last_rand(uint64_t imsi, uint8_t *rand) +{ + hss_ue_ctx_t *ue_ctx = NULL; + bool ret = get_ue_ctx(imsi, ue_ctx); + if(ret == false) + { + return; + } + memcpy(rand, ue_ctx->last_rand, 16); +} + void hss::gen_rand(uint8_t rand_[16]) { @@ -487,6 +614,19 @@ hss::gen_rand(uint8_t rand_[16]) return; } +bool hss::get_ue_ctx(uint64_t imsi, hss_ue_ctx_t *ue_ctx) +{ + std::map::iterator ue_ctx_it = m_imsi_to_ue_ctx.find(imsi); + if(ue_ctx_it == m_imsi_to_ue_ctx.end()) + { + m_hss_log->info("User not found. IMSI: %015lu\n",imsi); + return false; + } + + ue_ctx = ue_ctx_it->second; + return true; +} + /* Helper functions*/ std::vector hss::split_string(const std::string &str, char delimiter) From 244b68e76b6a1eb7de5cdb554a76cc8f35e02a46 Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Mon, 29 Jan 2018 14:01:13 +0100 Subject: [PATCH 11/46] Added authentication failure in s1ap --- srsepc/hdr/mme/s1ap_nas_transport.h | 3 +- srsepc/src/mme/s1ap_nas_transport.cc | 73 ++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index 2e9a1a9a7..5a457cec7 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -71,7 +71,8 @@ public: bool handle_esm_information_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag); bool handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag); bool handle_tracking_area_update_request(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag); - + bool handle_authentication_failure(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag); + bool pack_authentication_request(srslte::byte_buffer_t *reply_msg, uint32_t enb_ue_s1ap_id, uint32_t next_mme_ue_s1ap_id, uint8_t *autn,uint8_t *rand); bool pack_authentication_reject(srslte::byte_buffer_t *reply_msg, uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id); bool unpack_authentication_response(LIBLTE_S1AP_MESSAGE_UPLINKNASTRANSPORT_STRUCT *ul_xport, LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT *auth_resp); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 5aab70f16..e2f01f0b9 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -183,9 +183,14 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA //ue_ctx->security_ctxt.ul_nas_count++; break; case LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REQUEST: - m_s1ap_log->info("UL NAS: Tracking Area Update Request\n"); + m_s1ap_log->info("Uplink NAS: Tracking Area Update Request\n"); handle_tracking_area_update_request(nas_msg, ue_ctx, reply_buffer, reply_flag); break; + case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_FAILURE: + m_s1ap_log->info("Uplink NAS: Authentication Failure\n"); + handle_authentication_failure(nas_msg, ue_ctx, reply_buffer, reply_flag); + ue_ctx->security_ctxt.ul_nas_count++; + break; default: m_s1ap_log->warning("Unhandled NAS message 0x%x\n", msg_type ); m_s1ap_log->console("Unhandled NAS message 0x%x\n", msg_type ); @@ -590,7 +595,7 @@ s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ LIBLTE_MME_ID_RESPONSE_MSG_STRUCT id_resp; LIBLTE_ERROR_ENUM err = liblte_mme_unpack_identity_response_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &id_resp); if(err != LIBLTE_SUCCESS){ - m_s1ap_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]); + m_s1ap_log->error("Error unpacking NAS identity response. Error: %s\n", liblte_error_text[err]); return false; } @@ -615,8 +620,8 @@ s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ //Send reply to eNB *reply_flag = true; - m_s1ap_log->info("Downlink NAS: Sent Athentication Request\n"); - m_s1ap_log->console("Downlink NAS: Sent Athentication Request\n"); + m_s1ap_log->info("Downlink NAS: Sent Authentication Request\n"); + m_s1ap_log->console("Downlink NAS: Sent Authentication Request\n"); //TODO Start T3460 Timer! return true; @@ -696,6 +701,66 @@ s1ap_nas_transport::handle_tracking_area_update_request(srslte::byte_buffer_t *n } +bool +s1ap_nas_transport::handle_authentication_failure(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) +{ + uint8_t autn[16]; + uint8_t rand[16]; + uint8_t xres[8]; + + LIBLTE_MME_AUTHENTICATION_FAILURE_MSG_STRUCT auth_fail; + LIBLTE_ERROR_ENUM err = liblte_mme_unpack_authentication_failure_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &auth_fail); + if(err != LIBLTE_SUCCESS){ + m_s1ap_log->error("Error unpacking NAS authentication failure. Error: %s\n", liblte_error_text[err]); + return false; + } + + + switch(auth_fail.emm_cause){ + case 20: + m_s1ap_log->console("MAC code failure\n"); + m_s1ap_log->info("MAC code failure\n"); + break; + case 26: + m_s1ap_log->console("Non-EPS authentication unacceptable\n"); + m_s1ap_log->info("Non-EPS authentication unacceptable\n"); + break; + case 21: + m_s1ap_log->console("Sequence number synch failure\n"); + m_s1ap_log->info("Sequence number synch failure\n"); + if(auth_fail.auth_fail_param_present == false){ + m_s1ap_log->error("Missing fail parameter\n"); + return false; + } + if(!m_hss->resync_sqn(ue_ctx->imsi, auth_fail.auth_fail_param)) + { + m_s1ap_log->console("Resynchronization failed. IMSI %015lu\n", ue_ctx->imsi); + m_s1ap_log->info("Resynchronization failed. IMSI %015lu\n", ue_ctx->imsi); + return false; + } + //Get Authentication Vectors from HSS + if(!m_hss->gen_auth_info_answer(ue_ctx->imsi, ue_ctx->security_ctxt.k_asme, autn, rand, ue_ctx->security_ctxt.xres)) + { + m_s1ap_log->console("User not found. IMSI %015lu\n", ue_ctx->imsi); + m_s1ap_log->info("User not found. IMSI %015lu\n", ue_ctx->imsi); + return false; + } + + //Pack NAS Authentication Request in Downlink NAS Transport msg + pack_authentication_request(reply_msg, ue_ctx->enb_ue_s1ap_id, ue_ctx->mme_ue_s1ap_id, autn, rand); + + //Send reply to eNB + *reply_flag = true; + m_s1ap_log->info("Downlink NAS: Sent Authentication Request\n"); + m_s1ap_log->console("Downlink NAS: Sent Authentication Request\n"); + //TODO Start T3460 Timer! + + break; + } + return true; + +} + /*Packing/Unpacking helper functions*/ bool s1ap_nas_transport::pack_authentication_request(srslte::byte_buffer_t *reply_msg, uint32_t enb_ue_s1ap_id, uint32_t next_mme_ue_s1ap_id, uint8_t *autn, uint8_t *rand) From 52e7082aee9f06502cd239b0560e9554c0001d89 Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Mon, 29 Jan 2018 14:58:46 +0100 Subject: [PATCH 12/46] Small bug fixes, debug print. MAC f1_star does not work --- srsepc/hdr/hss/hss.h | 2 +- srsepc/src/hss/hss.cc | 25 ++++++++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/srsepc/hdr/hss/hss.h b/srsepc/hdr/hss/hss.h index 6abd91a57..818feae49 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -109,7 +109,7 @@ private: bool set_auth_algo(std::string auth_algo); bool read_db_file(std::string db_file); bool write_db_file(std::string db_file); - bool get_ue_ctx(uint64_t imsi, hss_ue_ctx_t *ue_ctx); + bool get_ue_ctx(uint64_t imsi, hss_ue_ctx_t **ue_ctx); std::string hex_string(uint8_t *hex, int size); diff --git a/srsepc/src/hss/hss.cc b/srsepc/src/hss/hss.cc index 30cc2571b..c9a13f93a 100644 --- a/srsepc/src/hss/hss.cc +++ b/srsepc/src/hss/hss.cc @@ -256,6 +256,7 @@ hss::resync_sqn(uint64_t imsi, uint8_t *auts) ret = resync_sqn_milenage(imsi, auts); break; } + increment_sqn(imsi); return ret; } @@ -312,19 +313,21 @@ hss::resync_sqn_milenage(uint64_t imsi, uint8_t *auts) } m_hss_log->debug_hex(sqn_ms, 6, "SQN MS : "); + m_hss_log->debug_hex(amf, 2, "AMF : "); + uint8_t mac_s_tmp[8]; security_milenage_f1_star(k, op, last_rand, sqn_ms, amf, mac_s_tmp); m_hss_log->debug_hex(mac_s_tmp, 8, "MAC calc : "); - + /* for(int i=0; i<8; i++){ if(!(mac_s_tmp[i] == mac_s[i])){ m_hss_log->error("Calculated MAC does not match sent MAC\n"); return false; } } - + */ set_sqn(imsi, sqn_ms); return true; @@ -544,7 +547,7 @@ void hss::increment_sqn(uint64_t imsi) { hss_ue_ctx_t *ue_ctx = NULL; - bool ret = get_ue_ctx(imsi, ue_ctx); + bool ret = get_ue_ctx(imsi, &ue_ctx); if(ret == false) { return; @@ -553,14 +556,14 @@ hss::increment_sqn(uint64_t imsi) // Awkward 48 bit sqn and doing arithmetic uint64_t sqn = 0; uint8_t *p = (uint8_t *)&sqn; - + for(int i = 0; i < 6; i++) { p[5-i] = (uint8_t) ((ue_ctx->sqn[i])); } - + sqn++; - m_hss_log->debug("Incremented IMSI: %015lu SQN: %d", imsi, sqn); + m_hss_log->debug("Incremented SQN (IMSI: %015lu) SQN: %d\n", imsi, sqn); for(int i = 0; i < 6; i++){ ue_ctx->sqn[i] = p[5-i]; @@ -571,7 +574,7 @@ void hss::set_sqn(uint64_t imsi, uint8_t *sqn) { hss_ue_ctx_t *ue_ctx = NULL; - bool ret = get_ue_ctx(imsi, ue_ctx); + bool ret = get_ue_ctx(imsi, &ue_ctx); if(ret == false) { return; @@ -583,7 +586,7 @@ void hss::set_last_rand(uint64_t imsi, uint8_t *rand) { hss_ue_ctx_t *ue_ctx = NULL; - bool ret = get_ue_ctx(imsi, ue_ctx); + bool ret = get_ue_ctx(imsi, &ue_ctx); if(ret == false) { return; @@ -596,7 +599,7 @@ void hss::get_last_rand(uint64_t imsi, uint8_t *rand) { hss_ue_ctx_t *ue_ctx = NULL; - bool ret = get_ue_ctx(imsi, ue_ctx); + bool ret = get_ue_ctx(imsi, &ue_ctx); if(ret == false) { return; @@ -614,7 +617,7 @@ hss::gen_rand(uint8_t rand_[16]) return; } -bool hss::get_ue_ctx(uint64_t imsi, hss_ue_ctx_t *ue_ctx) +bool hss::get_ue_ctx(uint64_t imsi, hss_ue_ctx_t **ue_ctx) { std::map::iterator ue_ctx_it = m_imsi_to_ue_ctx.find(imsi); if(ue_ctx_it == m_imsi_to_ue_ctx.end()) @@ -623,7 +626,7 @@ bool hss::get_ue_ctx(uint64_t imsi, hss_ue_ctx_t *ue_ctx) return false; } - ue_ctx = ue_ctx_it->second; + *ue_ctx = ue_ctx_it->second; return true; } From f3b1fe0f1a418c60ac7611ae60730755a6243639 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 30 Jan 2018 15:19:26 +0100 Subject: [PATCH 13/46] update for null-termination of strings fix --- lib/src/phy/phch/test/pdsch_test.c | 2 +- srsenb/src/enb_cfg_parser.cc | 2 +- srsue/src/upper/gw.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/phy/phch/test/pdsch_test.c b/lib/src/phy/phch/test/pdsch_test.c index 3e4aa5abc..4053176d9 100644 --- a/lib/src/phy/phch/test/pdsch_test.c +++ b/lib/src/phy/phch/test/pdsch_test.c @@ -111,7 +111,7 @@ void parse_args(int argc, char **argv) { cfi = atoi(argv[optind]); break; case 'x': - strncpy(mimo_type_str, argv[optind], sizeof(mimo_type_str)); + strncpy(mimo_type_str, argv[optind], sizeof(mimo_type_str)-1); mimo_type_str[sizeof(mimo_type_str)-1] = 0; break; case 'p': diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 6438a342e..ab25d9dcc 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -715,7 +715,7 @@ int enb::parse_sib9(std::string filename, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_9_STRUC if (!parser::parse_section(filename, &sib9)) { data->hnb_name_present = true; if (name_enabled) { - strncpy((char*) data->hnb_name, hnb_name.c_str(), 48); + strncpy((char*) data->hnb_name, hnb_name.c_str(), 47); data->hnb_name[47] = 0; data->hnb_name_size = strnlen(hnb_name.c_str(), 48); } else if (hex_enabled) { diff --git a/srsue/src/upper/gw.cc b/srsue/src/upper/gw.cc index 5bc94d3e7..65748f57b 100644 --- a/srsue/src/upper/gw.cc +++ b/srsue/src/upper/gw.cc @@ -201,7 +201,7 @@ srslte::error_t gw::init_if(char *err_str) } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TUN | IFF_NO_PI; - strncpy(ifr.ifr_ifrn.ifrn_name, dev, IFNAMSIZ); + strncpy(ifr.ifr_ifrn.ifrn_name, dev, IFNAMSIZ-1); ifr.ifr_ifrn.ifrn_name[IFNAMSIZ-1] = 0; if(0 > ioctl(tun_fd, TUNSETIFF, &ifr)) { From 6142b66632314ce9426a2851791d97e5adfa1473 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 5 Feb 2018 15:10:05 +0100 Subject: [PATCH 14/46] only print print buffer pool when it's empty --- lib/include/srslte/common/buffer_pool.h | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index 81a6025a8..a4186a78b 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -99,7 +99,6 @@ public: if (is_almost_empty()) { printf("Warning buffer pool capacity is %f %%\n", (float) 100*available.size()/capacity); - print_all_buffers(); } #ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED if (debug_name) { From 4e5f7f6ffa0bfcc8e3a58b117f405c5e633d4088 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 5 Feb 2018 15:12:16 +0100 Subject: [PATCH 15/46] rlc_am: flush retx queue after rx'ing status PDU to avoid unordered SNs --- lib/src/upper/rlc_am.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 76eb10da4..862a21085 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -963,6 +963,11 @@ void rlc_am::handle_control_pdu(uint8_t *payload, uint32_t nof_bytes) poll_retx_timeout.reset(); + // flush retx queue to avoid unordered SNs, we expect the Rx to request lost PDUs again + if (status.N_nack > 0) { + retx_queue.clear(); + } + // Handle ACKs and NACKs std::map::iterator it; bool update_vt_a = true; From 9484887f80f7daa92934fa611a6fe0c4fb9376f7 Mon Sep 17 00:00:00 2001 From: Merlin Chlosta Date: Mon, 5 Feb 2018 16:04:14 +0100 Subject: [PATCH 16/46] Write Identity Response to PCAP --- srsue/src/upper/nas.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 67305aaa3..04b5f4869 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -665,6 +665,11 @@ void nas::parse_identity_request(uint32_t lcid, byte_buffer_t *pdu) { pdu->reset(); liblte_mme_pack_identity_response_msg(&id_resp, (LIBLTE_BYTE_MSG_STRUCT *) pdu); + + if(pcap != NULL) { + pcap->write_nas(pdu->msg, pdu->N_bytes); + } + rrc->write_sdu(lcid, pdu); } From afe6219d4b7eb49be5916a8f754ffc27174e9562 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Feb 2018 15:20:33 +0100 Subject: [PATCH 17/46] rlc_am: move check for special SO_end field outside of if and adjust length accordingly --- lib/src/upper/rlc_am.cc | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 862a21085..33e6a0ba7 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -991,15 +991,26 @@ void rlc_am::handle_control_pdu(uint8_t *payload, uint32_t nof_bytes) retx.so_end = it->second.buf->N_bytes; if(status.nacks[j].has_so) { + // sanity check + if (status.nacks[j].so_start >= it->second.buf->N_bytes) { + // print error but try to send original PDU again + log->error("SO_start is larger than original PDU (%d >= %d)\n", + status.nacks[j].so_start, + it->second.buf->N_bytes); + status.nacks[j].so_start = 0; + } + + // check for special SO_end value + if(status.nacks[j].so_end == 0x7FFF) { + status.nacks[j].so_end = it->second.buf->N_bytes; + }else{ + retx.so_end = status.nacks[j].so_end + 1; + } + if(status.nacks[j].so_start < it->second.buf->N_bytes && status.nacks[j].so_end <= it->second.buf->N_bytes) { retx.is_segment = true; retx.so_start = status.nacks[j].so_start; - if(status.nacks[j].so_end == 0x7FFF) { - retx.so_end = it->second.buf->N_bytes; - }else{ - retx.so_end = status.nacks[j].so_end + 1; - } } else { log->warning("%s invalid segment NACK received for SN %d. so_start: %d, so_end: %d, N_bytes: %d\n", rrc->get_rb_name(lcid).c_str(), i, status.nacks[j].so_start, status.nacks[j].so_end, it->second.buf->N_bytes); From d9c5567e55c28481d7ec72a7302cbc3a746d7cec Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Feb 2018 15:23:36 +0100 Subject: [PATCH 18/46] rlc_am: request status PDU if needed when sending PDU segments --- lib/src/upper/rlc_am.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 33e6a0ba7..6c83be603 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -534,12 +534,21 @@ int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t r new_header.dc = RLC_DC_FIELD_DATA_PDU; new_header.rf = 1; - new_header.p = 0; new_header.fi = RLC_FI_FIELD_NOT_START_OR_END_ALIGNED; new_header.sn = old_header.sn; new_header.lsf = 0; new_header.so = retx.so_start; new_header.N_li = 0; + new_header.p = 0; + if(poll_required()) + { + log->debug("%s setting poll bit to request status\n", rrc->get_rb_name(lcid).c_str()); + new_header.p = 1; + poll_sn = vt_s; + pdu_without_poll = 0; + byte_without_poll = 0; + poll_retx_timeout.start(cfg.t_poll_retx); + } uint32_t head_len = 0; uint32_t pdu_space = 0; From 897db045bbeb0a3c5edaf9408d7bbd9f6ef98760 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Feb 2018 15:31:09 +0100 Subject: [PATCH 19/46] rlc_am: request status PDU if tx window is half full The idea behind this condition is to prevent pushing more and more data PDU on the tx_queue without getting feedback from the receiver about it's state. --- lib/src/upper/rlc_am.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 6c83be603..26e0d39d2 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -406,6 +406,10 @@ bool rlc_am::poll_required() if(tx_sdu_queue.size() == 0 && retx_queue.size() == 0) return true; + // Request status if Tx window is half-full + if (tx_window.size() >= RLC_AM_WINDOW_SIZE/2) + return true; + /* According to 5.2.2.1 in 36.322 v13.3.0 a poll should be requested if * the entire AM window is unacknowledged, i.e. no new PDU can be transmitted. * However, it seems more appropiate to request more often if polling From fa7d5bd40e73eb0f4b1da783fa140857c4751b7b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Feb 2018 16:59:20 +0100 Subject: [PATCH 20/46] rlc_am: retransmit first outstanding PDU in case the tx_window is full to avoid stalling --- lib/src/upper/rlc_am.cc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 26e0d39d2..3f976bd91 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -312,6 +312,23 @@ int rlc_am::read_pdu(uint8_t *payload, uint32_t nof_bytes) pthread_mutex_unlock(&mutex); return build_status_pdu(payload, nof_bytes); } + + // if tx_window is full and retx_queue empty, retransmit next PDU to be ack'ed + if (tx_window.size() >= RLC_AM_WINDOW_SIZE && retx_queue.size() == 0) { + // make sure this SN is still in the Tx window + uint32_t retx_sn = vt_a; + while (tx_window[retx_sn].buf == NULL) { + retx_sn++; + } + + rlc_amd_retx_t retx; + retx.is_segment = false; + retx.so_start = 0; + retx.so_end = tx_window[retx_sn].buf->N_bytes; + retx.sn = retx_sn; + retx_queue.push_back(retx); + } + // RETX if required if(retx_queue.size() > 0) { int ret = build_retx_pdu(payload, nof_bytes); From 1fd2341932993ea777c8713f12b8def871ea4f40 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Wed, 7 Feb 2018 09:37:26 +0000 Subject: [PATCH 21/46] Minor typo fix --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a21ed4fa9..d67985c49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -371,7 +371,7 @@ if(RF_FOUND) message(STATUS "Building with srsENB") add_subdirectory(srsenb) else(ENABLE_SRSENB) - message(STATUS "srsUE build disabled") + message(STATUS "srsENB build disabled") endif(ENABLE_SRSENB) else(RF_FOUND) message(STATUS "srsUE and srsENB builds disabled due to missing RF driver") From 705acec6b9daa3cec5e8dd5f32e7d9b6179b5717 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 7 Feb 2018 14:45:44 +0100 Subject: [PATCH 22/46] fix uninitialized variables in logger --- lib/include/srslte/common/log.h | 2 ++ lib/src/common/logger_file.cc | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/include/srslte/common/log.h b/lib/include/srslte/common/log.h index 93f7657cb..ff3a31eaa 100644 --- a/lib/include/srslte/common/log.h +++ b/lib/include/srslte/common/log.h @@ -70,6 +70,7 @@ public: level = LOG_LEVEL_NONE; hex_limit = 0; show_layer_en = true; + add_string_en = false; level_text_short = true; } @@ -79,6 +80,7 @@ public: level = LOG_LEVEL_NONE; hex_limit = 0; show_layer_en = true; + add_string_en = false; level_text_short = true; } diff --git a/lib/src/common/logger_file.cc b/lib/src/common/logger_file.cc index 18dc64974..f7532fdd1 100644 --- a/lib/src/common/logger_file.cc +++ b/lib/src/common/logger_file.cc @@ -36,6 +36,8 @@ namespace srslte{ logger_file::logger_file() :inited(false) ,not_done(true) + ,cur_length(0) + ,max_length(0) {} logger_file::~logger_file() { @@ -48,11 +50,11 @@ logger_file::~logger_file() { } } -void logger_file::init(std::string file, int max_length) { +void logger_file::init(std::string file, int max_length_) { pthread_mutex_init(&mutex, NULL); pthread_cond_init(¬_empty, NULL); pthread_cond_init(¬_full, NULL); - this->max_length = max_length*1024; + max_length = max_length_*1024; name_idx = 0; filename = file; logfile = fopen(filename.c_str(), "w"); From 9c3418d010fe502abbda08338b3e7ac951c69adb Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 7 Feb 2018 16:29:31 +0100 Subject: [PATCH 23/46] rlc_am: add extra brackets to macro --- lib/src/upper/rlc_am.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 3f976bd91..faa9600f4 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -31,8 +31,8 @@ #include #define MOD 1024 -#define RX_MOD_BASE(x) (x-vr_r)%1024 -#define TX_MOD_BASE(x) (x-vt_a)%1024 +#define RX_MOD_BASE(x) ((x-vr_r)%1024) +#define TX_MOD_BASE(x) ((x-vt_a)%1024) namespace srslte { From bebf062feefb891259d41d7e07c846cd5249d129 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 7 Feb 2018 16:32:15 +0100 Subject: [PATCH 24/46] rlc_am: count poll_pdu and poll_byte during retransmission (and segements) --- lib/src/upper/rlc_am.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index faa9600f4..2ecb862d5 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -514,6 +514,12 @@ int rlc_am::build_retx_pdu(uint8_t *payload, uint32_t nof_bytes) // Update & write header rlc_amd_pdu_header_t new_header = tx_window[retx.sn].header; new_header.p = 0; + + // Set poll bit + pdu_without_poll++; + byte_without_poll += (tx_window[retx.sn].buf->N_bytes + rlc_am_packed_length(&new_header)); + log->info("%s pdu_without_poll: %d\n", rrc->get_rb_name(lcid).c_str(), pdu_without_poll); + log->info("%s byte_without_poll: %d\n", rrc->get_rb_name(lcid).c_str(), byte_without_poll); if(poll_required()) { new_header.p = 1; @@ -553,6 +559,11 @@ int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t r rlc_amd_pdu_header_t new_header; rlc_amd_pdu_header_t old_header = tx_window[retx.sn].header; + pdu_without_poll++; + byte_without_poll += (tx_window[retx.sn].buf->N_bytes + rlc_am_packed_length(&new_header)); + log->info("%s pdu_without_poll: %d\n", rrc->get_rb_name(lcid).c_str(), pdu_without_poll); + log->info("%s byte_without_poll: %d\n", rrc->get_rb_name(lcid).c_str(), byte_without_poll); + new_header.dc = RLC_DC_FIELD_DATA_PDU; new_header.rf = 1; new_header.fi = RLC_FI_FIELD_NOT_START_OR_END_ALIGNED; From 7fde6e49334f90d912418bff2d4e247d4522ab86 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 7 Feb 2018 16:34:10 +0100 Subject: [PATCH 25/46] rlc_am: fix conditions for resetting re-ordering timer --- lib/src/upper/rlc_am.cc | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 2ecb862d5..14ce81292 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -892,12 +892,7 @@ void rlc_am::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_h // Update reordering variables and timers (36.322 v10.0.0 Section 5.1.3.2.3) if(reordering_timeout.is_running()) { - if( - vr_x == vr_r || - (RX_MOD_BASE(vr_x) < RX_MOD_BASE(vr_r) || - (RX_MOD_BASE(vr_x) > RX_MOD_BASE(vr_mr) && - vr_x != vr_mr)) - ) + if(vr_x == vr_r || (!inside_rx_window(vr_x) && vr_x != vr_mr)) { reordering_timeout.reset(); } From eb8a884e908ce3b7da760db58414dacc76c31f59 Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 7 Feb 2018 16:51:23 +0000 Subject: [PATCH 26/46] small optimization in neon viterbi --- lib/src/phy/fec/viterbi37_neon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/fec/viterbi37_neon.c b/lib/src/phy/fec/viterbi37_neon.c index 452dba567..82ed190cc 100644 --- a/lib/src/phy/fec/viterbi37_neon.c +++ b/lib/src/phy/fec/viterbi37_neon.c @@ -176,7 +176,7 @@ void print_uint8x16_t(char *s, uint8x16_t val) { printf("\n"); } -int movemask_neon(uint8x16_t movemask_low_in) +static inline int movemask_neon(uint8x16_t movemask_low_in) { uint8x8_t lo = vget_low_u8(movemask_low_in); uint8x8_t hi = vget_high_u8(movemask_low_in); From 34233e64a4deec5ce3a27bc3a7812dca26ea58ee Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 6 Feb 2018 12:33:26 +0100 Subject: [PATCH 27/46] Fixed SNR source from equalizer to average --- srsue/src/phy/phch_worker.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 720f0557e..6951574f5 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -367,7 +367,7 @@ void phch_worker::work_imp() update_measurements(); if (chest_ok) { - if (phy->avg_rsrp_dbm > -130.0 && 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)) > -30.0) { + if (phy->avg_rsrp_dbm > -130.0 && phy->avg_snr_db > -30.0) { log_h->debug("SNR=%.1f dB, RSRP=%.1f dBm sync=in-sync from channel estimator\n", 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)), phy->avg_rsrp_dbm); chest_loop->in_sync(); From 0c2f0ac03844e4879978d994b8b4b1bc0dba1d97 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 7 Feb 2018 18:36:06 +0100 Subject: [PATCH 28/46] Fixed srsue freq_offset compensation for UL --- lib/include/srslte/radio/radio.h | 1 + lib/src/radio/radio.cc | 5 ++++ srsue/hdr/phy/phch_worker.h | 2 ++ srsue/src/phy/phch_worker.cc | 47 ++++++++++++++++++++++++++++---- 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/lib/include/srslte/radio/radio.h b/lib/include/srslte/radio/radio.h index 6ff0c5100..454f1578f 100644 --- a/lib/include/srslte/radio/radio.h +++ b/lib/include/srslte/radio/radio.h @@ -101,6 +101,7 @@ namespace srslte { void set_tx_freq(double freq); void set_rx_freq(double freq); + double get_freq_offset(); double get_tx_freq(); double get_rx_freq(); diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index f592db71f..f3baad4a5 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -313,6 +313,11 @@ double radio::get_rx_freq() return rx_freq; } +double radio::get_freq_offset() +{ + return freq_offset; +} + double radio::get_tx_freq() { return tx_freq; diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index d73214514..c154ff514 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -70,6 +70,8 @@ public: void start_plot(); float get_ref_cfo(); + float get_cfo(); + float get_ul_cfo(); private: /* Inherited from thread_pool::worker. Function called every subframe to run the DL/UL processing */ diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 6951574f5..f7e1381f8 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -203,6 +203,25 @@ float phch_worker::get_ref_cfo() return srslte_chest_dl_get_cfo(&ue_dl.chest); } +float phch_worker::get_cfo() +{ + return cfo; +} + +float phch_worker::get_ul_cfo() { + srslte::radio *radio = phy->get_radio(); + + if (radio->get_freq_offset() != 0.0f) { + /* Compensates the radio frequency offset applied equally to DL and UL */ + const float ul_dl_ratio = (float) radio->get_tx_freq() / (float) radio->get_rx_freq(); + const float offset_hz = (float) radio->get_freq_offset() * (1.0f - ul_dl_ratio); + return cfo - offset_hz / (15000); + } else { + return cfo; + } + +} + void phch_worker::work_imp() { if (!cell_initiated) { @@ -324,7 +343,7 @@ void phch_worker::work_imp() } /* Set UL CFO before transmission */ - srslte_ue_ul_set_cfo(&ue_ul, cfo); + srslte_ue_ul_set_cfo(&ue_ul, get_ul_cfo()); /* Transmit PUSCH, PUCCH or SRS */ bool signal_ready = false; @@ -1476,6 +1495,13 @@ plot_scatter_t pconst; float tmp_plot[SCATTER_PDSCH_BUFFER_LEN]; cf_t tmp_plot2[SRSLTE_SF_LEN_RE(SRSLTE_MAX_PRB, SRSLTE_CP_NORM)]; +#define CFO_PLOT_LEN 0 /* Set to non zero for enabling CFO plot */ +#if CFO_PLOT_LEN > 0 +static plot_real_t pcfo; +static uint32_t icfo = 0; +static float cfo_buffer[CFO_PLOT_LEN]; +#endif /* CFO_PLOT_LEN > 0 */ + void *plot_thread_run(void *arg) { srsue::phch_worker *worker = (srsue::phch_worker*) arg; @@ -1500,10 +1526,14 @@ void *plot_thread_run(void *arg) { plot_scatter_addToWindowGrid(&pconst, (char*)"srsue", 0, worker->get_rx_nof_antennas()); +#if CFO_PLOT_LEN > 0 + plot_real_init(&pcfo); + plot_real_setTitle(&pcfo, (char*) "CFO (Hz)"); + plot_real_setLabels(&pcfo, (char *) "Time", (char *) "Hz"); + plot_real_setYAxisScale(&pcfo, -4000, 4000); - - - + plot_scatter_addToWindowGrid(&pcfo, (char*)"srsue", 1, worker->get_rx_nof_antennas()); +#endif /* CFO_PLOT_LEN > 0 */ int n; int readed_pdsch_re=0; @@ -1527,7 +1557,14 @@ void *plot_thread_run(void *arg) { } readed_pdsch_re = 0; } - } + +#if CFO_PLOT_LEN > 0 + cfo_buffer[icfo] = worker->get_cfo() * 15000.0f; + icfo = (icfo + 1)%CFO_PLOT_LEN; + plot_real_setNewData(&pcfo, cfo_buffer, CFO_PLOT_LEN); +#endif /* CFO_PLOT_LEN > 0 */ + + } return NULL; } From fe069073f042a99e5fa1529779c57b3dd120c7fe Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 7 Feb 2018 20:47:49 +0100 Subject: [PATCH 29/46] rlc_am: directly add lower edge of tx window in case of a retx --- lib/src/upper/rlc_am.cc | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 14ce81292..6fdf52966 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -315,18 +315,17 @@ int rlc_am::read_pdu(uint8_t *payload, uint32_t nof_bytes) // if tx_window is full and retx_queue empty, retransmit next PDU to be ack'ed if (tx_window.size() >= RLC_AM_WINDOW_SIZE && retx_queue.size() == 0) { - // make sure this SN is still in the Tx window - uint32_t retx_sn = vt_a; - while (tx_window[retx_sn].buf == NULL) { - retx_sn++; + if (tx_window[vt_a].buf != NULL) { + log->warning("Full Tx window, ReTx'ing first outstanding PDU\n"); + rlc_amd_retx_t retx; + retx.is_segment = false; + retx.so_start = 0; + retx.so_end = tx_window[vt_a].buf->N_bytes; + retx.sn = vt_a; + retx_queue.push_back(retx); + } else { + log->error("Found invalid PDU in tx_window.\n"); } - - rlc_amd_retx_t retx; - retx.is_segment = false; - retx.so_start = 0; - retx.so_end = tx_window[retx_sn].buf->N_bytes; - retx.sn = retx_sn; - retx_queue.push_back(retx); } // RETX if required From bfb3155da681e5ac3bfffda38de6bbb55f6b820c Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 7 Feb 2018 20:49:04 +0100 Subject: [PATCH 30/46] rlc_am: don't build new PDUs if tx window is full --- lib/src/upper/rlc_am.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 6fdf52966..c1129ff51 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -676,6 +676,12 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) return 0; } + // do not build any more PDU if window is already full + if (!tx_sdu && tx_window.size() >= RLC_AM_WINDOW_SIZE) { + log->info("Tx window full.\n"); + return 0; + } + byte_buffer_t *pdu = pool_allocate; if (!pdu) { log->console("Fatal Error: Could not allocate PDU in build_data_pdu()\n"); From bde37de866486ae70585602de021a1b074aa1c62 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 7 Feb 2018 20:50:03 +0100 Subject: [PATCH 31/46] rlc_am: fix bug where PDU was erased from tx_window too early --- lib/src/upper/rlc_am.cc | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index c1129ff51..02945aaa8 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -1069,17 +1069,16 @@ void rlc_am::handle_control_pdu(uint8_t *payload, uint32_t nof_bytes) //ACKed SNs get marked and removed from tx_window if possible if(tx_window.count(i) > 0) { it = tx_window.find(i); - it->second.is_acked = true; - if(it->second.buf) { - pool->deallocate(it->second.buf); - it->second.buf = 0; - log->info("SN=%d removed from tx_window\n", i); - } - tx_window.erase(it); - if(update_vt_a) - { - vt_a = (vt_a + 1)%MOD; - vt_ms = (vt_ms + 1)%MOD; + if (it != tx_window.end()) { + if(update_vt_a) { + tx_window.erase(it); + if(it->second.buf) { + pool->deallocate(it->second.buf); + it->second.buf = 0; + } + vt_a = (vt_a + 1)%MOD; + vt_ms = (vt_ms + 1)%MOD; + } } } } From 0c03b84a29640305bdfee0a5dc9f6ddfcf3d895e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 7 Feb 2018 20:52:26 +0100 Subject: [PATCH 32/46] Revert "rlc_am: request status PDU if tx window is half full" This reverts commit 897db045bbeb0a3c5edaf9408d7bbd9f6ef98760. --- lib/src/upper/rlc_am.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 02945aaa8..b360b24c8 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -422,10 +422,6 @@ bool rlc_am::poll_required() if(tx_sdu_queue.size() == 0 && retx_queue.size() == 0) return true; - // Request status if Tx window is half-full - if (tx_window.size() >= RLC_AM_WINDOW_SIZE/2) - return true; - /* According to 5.2.2.1 in 36.322 v13.3.0 a poll should be requested if * the entire AM window is unacknowledged, i.e. no new PDU can be transmitted. * However, it seems more appropiate to request more often if polling From 60b059f3cc366f0cd2c0f22e45083f4b51301696 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Wed, 7 Feb 2018 21:59:50 +0000 Subject: [PATCH 33/46] Adding RLC AM stress test --- lib/include/srslte/upper/rlc.h | 6 +- lib/test/upper/CMakeLists.txt | 4 + lib/test/upper/rlc_am_stress_test.cc | 242 +++++++++++++++++++++++++++ 3 files changed, 249 insertions(+), 3 deletions(-) create mode 100644 lib/test/upper/rlc_am_stress_test.cc diff --git a/lib/include/srslte/upper/rlc.h b/lib/include/srslte/upper/rlc.h index 17f6bd82c..e9036a011 100644 --- a/lib/include/srslte/upper/rlc.h +++ b/lib/include/srslte/upper/rlc.h @@ -55,9 +55,9 @@ public: void init(srsue::pdcp_interface_rlc *pdcp_, srsue::rrc_interface_rlc *rrc_, srsue::ue_interface *ue_, - log *rlc_log_, - mac_interface_timers *mac_timers_, - uint32_t lcid_); + log *rlc_log_, + mac_interface_timers *mac_timers_, + uint32_t lcid_); void stop(); void get_metrics(rlc_metrics_t &m); diff --git a/lib/test/upper/CMakeLists.txt b/lib/test/upper/CMakeLists.txt index 82072c004..2a65dedb6 100644 --- a/lib/test/upper/CMakeLists.txt +++ b/lib/test/upper/CMakeLists.txt @@ -30,6 +30,10 @@ add_executable(rlc_am_test rlc_am_test.cc) target_link_libraries(rlc_am_test srslte_upper srslte_phy srslte_common) add_test(rlc_am_test rlc_am_test) +add_executable(rlc_am_stress_test rlc_am_stress_test.cc) +target_link_libraries(rlc_am_stress_test srslte_upper srslte_phy srslte_common) +add_test(rlc_am_stress_test rlc_am_stress_test) + add_executable(rlc_um_data_test rlc_um_data_test.cc) target_link_libraries(rlc_um_data_test srslte_upper srslte_phy srslte_common) add_test(rlc_um_data_test rlc_um_data_test) diff --git a/lib/test/upper/rlc_am_stress_test.cc b/lib/test/upper/rlc_am_stress_test.cc new file mode 100644 index 000000000..d3e24751b --- /dev/null +++ b/lib/test/upper/rlc_am_stress_test.cc @@ -0,0 +1,242 @@ +/** + * + * \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 +#include +#include +#include "srslte/common/log_filter.h" +#include "srslte/common/logger_stdout.h" +#include "srslte/common/threads.h" +#include "srslte/upper/rlc.h" +#include +#define NBUFS 5 + +using namespace srsue; +using namespace srslte; + +class mac_reader + :public thread +{ +public: + mac_reader(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_) + { + rlc1 = rlc1_; + rlc2 = rlc2_; + fail_rate = fail_rate_; + run_enable = true; + } + + void stop() + { + run_enable = false; + int cnt=0; + while(running && cnt<100) { + usleep(10000); + cnt++; + } + if(running) { + thread_cancel(); + } + wait_thread_finish(); + } + +private: + void run_thread() + { + running = true; + byte_buffer_t *pdu = byte_buffer_pool::get_instance()->allocate(); + + while(run_enable) { + float r = (float)rand()/RAND_MAX; + int opp_size = r*1500; + rlc1->get_buffer_state(1); + int read = rlc1->read_pdu(1, pdu->msg, opp_size); + if(((float)rand()/RAND_MAX > fail_rate) && read>0) { + rlc2->write_pdu(1, pdu->msg, opp_size); + } + usleep(1000); + } + running = false; + } + + rlc_interface_mac *rlc1; + rlc_interface_mac *rlc2; + float fail_rate; + + bool run_enable; + bool running; +}; + +class mac_dummy + :public srslte::mac_interface_timers +{ +public: + mac_dummy(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_) + :r1(rlc1_, rlc2_, fail_rate_) + ,r2(rlc2_, rlc1_, fail_rate_) + { + } + + void start() + { + r1.start(7); + r2.start(7); + } + + void stop() + { + r1.stop(); + r2.stop(); + } + + srslte::timers::timer* timer_get(uint32_t timer_id) + { + return &t; + } + uint32_t timer_get_unique_id(){return 0;} + void timer_release_id(uint32_t id){} + +private: + srslte::timers::timer t; + + mac_reader r1; + mac_reader r2; +}; + + + +class rlc_am_tester + :public pdcp_interface_rlc + ,public rrc_interface_rlc + ,public thread +{ +public: + rlc_am_tester(rlc_interface_pdcp *rlc_){ + rlc = rlc_; + run_enable = true; + } + + void stop() + { + run_enable = false; + int cnt=0; + while(running && cnt<100) { + usleep(10000); + cnt++; + } + if(running) { + thread_cancel(); + } + wait_thread_finish(); + } + + // PDCP interface + void write_pdu(uint32_t lcid, byte_buffer_t *sdu) + { + assert(lcid == 1); + byte_buffer_pool::get_instance()->deallocate(sdu); + } + void write_pdu_bcch_bch(byte_buffer_t *sdu) {} + void write_pdu_bcch_dlsch(byte_buffer_t *sdu) {} + void write_pdu_pcch(byte_buffer_t *sdu) {} + + // RRC interface + void max_retx_attempted(){} + std::string get_rb_name(uint32_t lcid) { return std::string(""); } + +private: + void run_thread() + { + uint8_t sn = 0; + running = true; + while(run_enable) { + byte_buffer_t *pdu = byte_buffer_pool::get_instance()->allocate(); + pdu->N_bytes = 1500; + pdu->msg[0] = sn++; + rlc->write_sdu(1, pdu); + usleep(1000); + } + running = false; + } + + bool run_enable; + bool running; + + rlc_interface_pdcp *rlc; +}; + +void stress_test() +{ + srslte::log_filter log1("RLC_AM_1"); + srslte::log_filter log2("RLC_AM_2"); + log1.set_level(srslte::LOG_LEVEL_DEBUG); + log2.set_level(srslte::LOG_LEVEL_DEBUG); + log1.set_hex_limit(-1); + log2.set_hex_limit(-1); + + float fail_rate = 0.1; + + rlc rlc1; + rlc rlc2; + + rlc_am_tester tester1(&rlc1); + rlc_am_tester tester2(&rlc2); + mac_dummy mac(&rlc1, &rlc2, fail_rate); + ue_interface ue; + + rlc1.init(&tester1, &tester1, &ue, &log1, &mac, 0); + rlc2.init(&tester1, &tester1, &ue, &log2, &mac, 0); + + LIBLTE_RRC_RLC_CONFIG_STRUCT cnfg; + cnfg.rlc_mode = LIBLTE_RRC_RLC_MODE_AM; + cnfg.dl_am_rlc.t_reordering = LIBLTE_RRC_T_REORDERING_MS5; + cnfg.dl_am_rlc.t_status_prohibit = LIBLTE_RRC_T_STATUS_PROHIBIT_MS5; + cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4; + cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25; + cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4; + cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5; + + srslte_rlc_config_t cnfg_(&cnfg); + + rlc1.add_bearer(1, cnfg_); + rlc2.add_bearer(1, cnfg_); + + tester1.start(7); + //tester2.start(7); + mac.start(); + + usleep(100e6); + + tester1.stop(); + tester2.stop(); + mac.stop(); +} + + +int main(int argc, char **argv) { + stress_test(); + byte_buffer_pool::get_instance()->cleanup(); +} From d1d6cea7370641dfdc15e938632ffb9a4502cc94 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Wed, 7 Feb 2018 23:13:59 +0000 Subject: [PATCH 34/46] Adding debug helpers --- lib/include/srslte/common/common.h | 2 +- lib/include/srslte/upper/rlc_am.h | 1 + lib/src/upper/rlc_am.cc | 20 ++++++++++++++++++-- lib/test/upper/rlc_am_stress_test.cc | 12 ++++++++++-- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/lib/include/srslte/common/common.h b/lib/include/srslte/common/common.h index 41a89fb36..ddd558016 100644 --- a/lib/include/srslte/common/common.h +++ b/lib/include/srslte/common/common.h @@ -63,7 +63,7 @@ #define SRSLTE_MAX_BUFFER_SIZE_BYTES 12756 #define SRSLTE_BUFFER_HEADER_OFFSET 1024 -//#define SRSLTE_BUFFER_POOL_LOG_ENABLED +#define SRSLTE_BUFFER_POOL_LOG_ENABLED #ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED #define pool_allocate (pool->allocate(__FUNCTION__)) diff --git a/lib/include/srslte/upper/rlc_am.h b/lib/include/srslte/upper/rlc_am.h index e28e11618..5a93750a4 100644 --- a/lib/include/srslte/upper/rlc_am.h +++ b/lib/include/srslte/upper/rlc_am.h @@ -189,6 +189,7 @@ private: bool inside_tx_window(uint16_t sn); bool inside_rx_window(uint16_t sn); void debug_state(); + void print_rx_segments(); bool add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rlc_amd_rx_pdu_t *segment); int required_buffer_size(rlc_amd_retx_t retx); diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index b360b24c8..d71ade7ca 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -587,7 +587,7 @@ int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t r rrc->get_rb_name(lcid).c_str(), nof_bytes, head_len); return 0; } - pdu_space = nof_bytes-head_len-2; + pdu_space = nof_bytes-head_len-1; if(pdu_space < (retx.so_end-retx.so_start)) retx.so_end = retx.so_start+pdu_space; @@ -606,7 +606,7 @@ int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t r upper += old_header.li[i]; head_len = rlc_am_packed_length(&new_header); - pdu_space = nof_bytes-head_len-2; + pdu_space = nof_bytes-head_len-1; if(pdu_space < (retx.so_end-retx.so_start)) retx.so_end = retx.so_start+pdu_space; @@ -934,6 +934,7 @@ void rlc_am::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a log->console("Fatal Error: Could not allocate PDU in handle_data_pdu_segment()\n"); exit(-1); } + memcpy(segment.buf->msg, payload, nof_bytes); segment.buf->N_bytes = nof_bytes; memcpy(&segment.header, &header, sizeof(rlc_amd_pdu_header_t)); @@ -986,6 +987,7 @@ void rlc_am::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a } } + print_rx_segments(); debug_state(); } @@ -1169,6 +1171,20 @@ void rlc_am::debug_state() } +void rlc_am::print_rx_segments() +{ + std::map::iterator it; + std::stringstream ss; + ss << "rx_segments:" << std::endl; + for(it=rx_segments.begin();it!=rx_segments.end();it++) { + std::list::iterator segit; + for(segit = it->second.segments.begin(); segit != it->second.segments.end(); segit++) { + ss << " SN:" << segit->header.sn << " SO:" << segit->header.so << " N:" << segit->buf->N_bytes << std::endl; + } + } + log->debug("%s\n", ss.str().c_str()); +} + bool rlc_am::add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rlc_amd_rx_pdu_t *segment) { // Ordered insert diff --git a/lib/test/upper/rlc_am_stress_test.cc b/lib/test/upper/rlc_am_stress_test.cc index d3e24751b..ad1a0c716 100644 --- a/lib/test/upper/rlc_am_stress_test.cc +++ b/lib/test/upper/rlc_am_stress_test.cc @@ -67,7 +67,11 @@ private: void run_thread() { running = true; - byte_buffer_t *pdu = byte_buffer_pool::get_instance()->allocate(); + byte_buffer_t *pdu = byte_buffer_pool::get_instance()->allocate("mac_reader::run_thread"); + if (!pdu) { + printf("Fatal Error: Could not allocate PDU in mac_reader::run_thread\n"); + exit(-1); + } while(run_enable) { float r = (float)rand()/RAND_MAX; @@ -173,7 +177,11 @@ private: uint8_t sn = 0; running = true; while(run_enable) { - byte_buffer_t *pdu = byte_buffer_pool::get_instance()->allocate(); + byte_buffer_t *pdu = byte_buffer_pool::get_instance()->allocate("rlc_am_tester::run_thread"); + if (!pdu) { + printf("Fatal Error: Could not allocate PDU in rlc_am_tester::run_thread\n"); + exit(-1); + } pdu->N_bytes = 1500; pdu->msg[0] = sn++; rlc->write_sdu(1, pdu); From bf26934e131229423934557f6ba5cd4a37dd353f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 8 Feb 2018 17:50:19 +0100 Subject: [PATCH 35/46] rlc_am: print error but don't exit on buffer allocation errors --- lib/include/srslte/upper/rlc_am.h | 2 +- lib/src/upper/rlc_am.cc | 44 +++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/lib/include/srslte/upper/rlc_am.h b/lib/include/srslte/upper/rlc_am.h index 5a93750a4..2311b23cb 100644 --- a/lib/include/srslte/upper/rlc_am.h +++ b/lib/include/srslte/upper/rlc_am.h @@ -40,7 +40,7 @@ namespace srslte { - +#undef RLC_AM_BUFFER_DEBUG struct rlc_amd_rx_pdu_t{ rlc_amd_pdu_header_t header; diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index d71ade7ca..c5a495c32 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -680,6 +680,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) byte_buffer_t *pdu = pool_allocate; if (!pdu) { +#ifdef RLC_AM_BUFFER_DEBUG log->console("Fatal Error: Could not allocate PDU in build_data_pdu()\n"); log->console("tx_window size: %d PDUs\n", tx_window.size()); log->console("vt_a = %d, vt_ms = %d, vt_s = %d, poll_sn = %d " @@ -692,6 +693,10 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) log->console("tx_window - SN: %d\n", txit->first); } exit(-1); +#else + log->error("Fatal Error: Couldn't allocate PDU in build_data_pdu().\n"); + return 0; +#endif } rlc_amd_pdu_header_t header; header.dc = RLC_DC_FIELD_DATA_PDU; @@ -850,8 +855,13 @@ void rlc_am::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_h rlc_amd_rx_pdu_t pdu; pdu.buf = pool_allocate; if (!pdu.buf) { - log->console("Fatal Error: Could not allocate PDU in handle_data_pdu()\n"); +#ifdef RLC_AM_BUFFER_DEBUG + log->console("Fatal Error: Couldn't allocate PDU in handle_data_pdu().\n"); exit(-1); +#else + log->error("Fatal Error: Couldn't allocate PDU in handle_data_pdu().\n"); + return; +#endif } memcpy(pdu.buf->msg, payload, nof_bytes); @@ -931,8 +941,13 @@ void rlc_am::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a rlc_amd_rx_pdu_t segment; segment.buf = pool_allocate; if (!segment.buf) { - log->console("Fatal Error: Could not allocate PDU in handle_data_pdu_segment()\n"); +#ifdef RLC_AM_BUFFER_DEBUG + log->console("Fatal Error: Couldn't allocate PDU in handle_data_pdu_segment().\n"); exit(-1); +#else + log->error("Fatal Error: Couldn't allocate PDU in handle_data_pdu_segment().\n"); + return; +#endif } memcpy(segment.buf->msg, payload, nof_bytes); @@ -1091,8 +1106,13 @@ void rlc_am::reassemble_rx_sdus() if(!rx_sdu) { rx_sdu = pool_allocate; if (!rx_sdu) { +#ifdef RLC_AM_BUFFER_DEBUG log->console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (1)\n"); exit(-1); +#else + log->error("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (1)\n"); + return; +#endif } } // Iterate through rx_window, assembling and delivering SDUs @@ -1111,10 +1131,14 @@ void rlc_am::reassemble_rx_sdus() pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; if (!rx_sdu) { +#ifdef RLC_AM_BUFFER_DEBUG log->console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (2)\n"); - exit(-1); + exit(-1); +#else + log->error("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (2)\n"); + return; +#endif } - } // Handle last segment @@ -1127,8 +1151,13 @@ void rlc_am::reassemble_rx_sdus() pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; if (!rx_sdu) { +#ifdef RLC_AM_BUFFER_DEBUG log->console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (3)\n"); - exit(-1); + exit(-1); +#else + log->error("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (3)\n"); + return; +#endif } } @@ -1243,8 +1272,13 @@ bool rlc_am::add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rlc_amd_rx_pd // Copy data byte_buffer_t *full_pdu = pool_allocate; if (!full_pdu) { +#ifdef RLC_AM_BUFFER_DEBUG log->console("Fatal Error: Could not allocate PDU in add_segment_and_check()\n"); exit(-1); +#else + log->error("Fatal Error: Could not allocate PDU in add_segment_and_check()\n"); + return false; +#endif } for(it = pdu->segments.begin(); it != pdu->segments.end(); it++) { memcpy(&full_pdu->msg[full_pdu->N_bytes], it->buf->msg, it->buf->N_bytes); From ed76d73bbcef8756a7a48d52a46521f82cb85f26 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 8 Feb 2018 20:57:36 +0100 Subject: [PATCH 36/46] Print tpc_pucch for format2 dci also --- lib/src/phy/phch/dci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/phy/phch/dci.c b/lib/src/phy/phch/dci.c index 6766ca5f0..7bb2f9c19 100644 --- a/lib/src/phy/phch/dci.c +++ b/lib/src/phy/phch/dci.c @@ -426,7 +426,8 @@ uint32_t srslte_dci_dl_info(char *info_str, uint32_t len, srslte_ra_dl_dci_t *dc n += snprintf(&info_str[n], len - n, "%d}, ", dci_msg->ndi_1); } - if (format == SRSLTE_DCI_FORMAT1 || format == SRSLTE_DCI_FORMAT1A || format == SRSLTE_DCI_FORMAT1B) { + if (format == SRSLTE_DCI_FORMAT1 || format == SRSLTE_DCI_FORMAT1A || format == SRSLTE_DCI_FORMAT1B || + format == SRSLTE_DCI_FORMAT2 || format == SRSLTE_DCI_FORMAT2A || format == SRSLTE_DCI_FORMAT2B) { n += snprintf(&info_str[n], len-n, "tpc_pucch=%d, ", dci_msg->tpc_pucch); } if (format == SRSLTE_DCI_FORMAT2 || format == SRSLTE_DCI_FORMAT2A || format == SRSLTE_DCI_FORMAT2B) { From 7ae186d4991f11098f0c47a808dfab2e94cceb0c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 8 Feb 2018 20:58:00 +0100 Subject: [PATCH 37/46] Typo in printing default pdsch_ue help --- lib/examples/pdsch_ue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index 1e17fa59d..74bac426d 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -162,8 +162,8 @@ void usage(prog_args_t *args, char *prog) { printf("\t-r RNTI in Hex [Default 0x%x]\n",args->rnti); printf("\t-l Force N_id_2 [Default best]\n"); printf("\t-C Disable CFO correction [Default %s]\n", args->disable_cfo?"Disabled":"Enabled"); - printf("\t-F Enable RS-based CFO correction [Default %s]\n", args->enable_cfo_ref?"Disabled":"Enabled"); - printf("\t-R Average channel estimates on 1 ms [Default %s]\n", args->average_subframe?"Disabled":"Enabled"); + printf("\t-F Enable RS-based CFO correction [Default %s]\n", !args->enable_cfo_ref?"Disabled":"Enabled"); + printf("\t-R Average channel estimates on 1 ms [Default %s]\n", !args->average_subframe?"Disabled":"Enabled"); printf("\t-t Add time offset [Default %d]\n", args->time_offset); #ifndef DISABLE_GRAPHICS printf("\t-d disable plots [Default enabled]\n"); From c429f3031f9c859ae1a9dded07dda6da5609f323 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 8 Feb 2018 20:58:43 +0100 Subject: [PATCH 38/46] Proper normalization to noise power estimation in chest_dl --- lib/src/phy/ch_estimation/chest_dl.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index d63933ced..98ff6618c 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -282,10 +282,14 @@ static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id, srslt /* Compute average power. Normalized for filter len 3 using matlab */ float norm = 1; - if (q->smooth_filter_len == 3) { - float a = q->smooth_filter[0]; - float norm3 = 6.143*a*a+0.04859*a-0.002774; - norm /= norm3; + if (q->average_subframe) { + norm = 32; + } else { + if (q->smooth_filter_len == 3) { + float a = q->smooth_filter[0]; + float norm3 = 6.143*a*a+0.04859*a-0.002774; + norm /= norm3; + } } float power = norm*q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_noise, nref); return power; From ddfd114865caddfc15005f7cf3cd0a51ed21dc20 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 9 Feb 2018 11:36:55 +0100 Subject: [PATCH 39/46] rlc_am: disable debug prints --- lib/include/srslte/common/common.h | 2 +- lib/src/upper/rlc_am.cc | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/include/srslte/common/common.h b/lib/include/srslte/common/common.h index ddd558016..41a89fb36 100644 --- a/lib/include/srslte/common/common.h +++ b/lib/include/srslte/common/common.h @@ -63,7 +63,7 @@ #define SRSLTE_MAX_BUFFER_SIZE_BYTES 12756 #define SRSLTE_BUFFER_HEADER_OFFSET 1024 -#define SRSLTE_BUFFER_POOL_LOG_ENABLED +//#define SRSLTE_BUFFER_POOL_LOG_ENABLED #ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED #define pool_allocate (pool->allocate(__FUNCTION__)) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index c5a495c32..affeba665 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -1001,8 +1001,9 @@ void rlc_am::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a // else delay for reordering timer } } - +#ifdef RLC_AM_BUFFER_DEBUG print_rx_segments(); +#endif debug_state(); } From ef19b5f0513879c208bc09d5d4ab322c9aaa9801 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 9 Feb 2018 11:37:21 +0100 Subject: [PATCH 40/46] rlc_am: revert PDU len changes to pass tests again --- lib/src/upper/rlc_am.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index affeba665..2c8b1fbfc 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -587,7 +587,7 @@ int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t r rrc->get_rb_name(lcid).c_str(), nof_bytes, head_len); return 0; } - pdu_space = nof_bytes-head_len-1; + pdu_space = nof_bytes-head_len-2; if(pdu_space < (retx.so_end-retx.so_start)) retx.so_end = retx.so_start+pdu_space; @@ -606,7 +606,7 @@ int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t r upper += old_header.li[i]; head_len = rlc_am_packed_length(&new_header); - pdu_space = nof_bytes-head_len-1; + pdu_space = nof_bytes-head_len-2; if(pdu_space < (retx.so_end-retx.so_start)) retx.so_end = retx.so_start+pdu_space; From 22117156b3de6ff508112b1a9887436c8f7bfcb4 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 9 Feb 2018 11:48:26 +0100 Subject: [PATCH 41/46] rlc_am: disable stress tester as test --- lib/test/upper/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/test/upper/CMakeLists.txt b/lib/test/upper/CMakeLists.txt index 2a65dedb6..8793118e7 100644 --- a/lib/test/upper/CMakeLists.txt +++ b/lib/test/upper/CMakeLists.txt @@ -32,7 +32,6 @@ add_test(rlc_am_test rlc_am_test) add_executable(rlc_am_stress_test rlc_am_stress_test.cc) target_link_libraries(rlc_am_stress_test srslte_upper srslte_phy srslte_common) -add_test(rlc_am_stress_test rlc_am_stress_test) add_executable(rlc_um_data_test rlc_um_data_test.cc) target_link_libraries(rlc_um_data_test srslte_upper srslte_phy srslte_common) From 3f002aca85f9a23226c3481b3619ae11ad798e94 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Fri, 9 Feb 2018 12:14:23 +0100 Subject: [PATCH 42/46] Corrected energy measurement of the RSRP --- lib/src/phy/ch_estimation/chest_dl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index 98ff6618c..3dae7f9e5 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -543,8 +543,7 @@ void chest_interpolate_noise_est(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, ui /* Compute RSRP for the channel estimates in this port */ uint32_t npilots = SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id); - float energy = cabsf(srslte_vec_acc_cc(q->pilot_estimates, npilots)/npilots); - q->rsrp[rxant_id][port_id] = energy*energy; + q->rsrp[rxant_id][port_id] = __real__ srslte_vec_dot_prod_conj_ccc(q->pilot_estimates, q->pilot_estimates, npilots) / npilots; q->rssi[rxant_id][port_id] = srslte_chest_dl_rssi(q, input, port_id); } From 42c561e77efea5ebdd21850d5164f2e8fda83f67 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Fri, 9 Feb 2018 12:27:22 +0100 Subject: [PATCH 43/46] UE channel estimator averages in sf by default --- srsue/src/main.cc | 2 +- srsue/ue.conf.example | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 7599c2476..4119b9f78 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -246,7 +246,7 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { "Applies Successive Interference Cancellation to PSS signals when searching for neighbour cells. Must be disabled if cells have identical channel and timing.") ("expert.average_subframe_enabled", - bpo::value(&args->expert.phy.average_subframe_enabled)->default_value(false), + bpo::value(&args->expert.phy.average_subframe_enabled)->default_value(true), "Averages in the time domain the channel estimates within 1 subframe. Needs accurate CFO correction.") ("expert.time_correct_period", diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 140662ac0..83bd8c67a 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -197,7 +197,7 @@ enable = false #sfo_correct_disable = false #sss_algorithm = full #estimator_fil_w = 0.1 -#average_subframe_enabled = false +#average_subframe_enabled = true #sic_pss_enabled = true #pregenerate_signals = false #metrics_csv_enable = false From fdc7a0d334027baeed4bca5ba8e2897c0fb9ed03 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 9 Feb 2018 15:30:31 +0000 Subject: [PATCH 44/46] Removed misleading print. --- srsepc/src/mme/s1ap_nas_transport.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index d18005dfb..083201ff6 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -656,7 +656,7 @@ s1ap_nas_transport::handle_tracking_area_update_request(srslte::byte_buffer_t *n dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ctx->enb_ue_s1ap_id; dw_nas->HandoverRestrictionList_present=false; dw_nas->SubscriberProfileIDforRFP_present=false; - m_s1ap_log->console("Tracking area accept to MME-UE S1AP Id %d\n", ue_ctx->mme_ue_s1ap_id); + //m_s1ap_log->console("Tracking area accept to MME-UE S1AP Id %d\n", ue_ctx->mme_ue_s1ap_id); LIBLTE_MME_TRACKING_AREA_UPDATE_ACCEPT_MSG_STRUCT tau_acc; /*typedef struct{ From 86818ad65f24c66293dfca3dd6faec5420f6b5f6 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 9 Feb 2018 17:36:44 +0100 Subject: [PATCH 45/46] Fix compilations warnings and remove printf debugs --- lib/include/srslte/common/threads.h | 5 ++++- lib/src/phy/phch/test/pdcch_test.c | 6 ++++-- lib/test/upper/rlc_am_stress_test.cc | 1 + srsenb/src/mac/scheduler.cc | 4 ++-- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/include/srslte/common/threads.h b/lib/include/srslte/common/threads.h index e87407870..949ece195 100644 --- a/lib/include/srslte/common/threads.h +++ b/lib/include/srslte/common/threads.h @@ -51,7 +51,10 @@ class thread { -public: +public: + thread() { + _thread = 0; + } bool start(int prio = -1) { return threads_new_rt_prio(&_thread, thread_function_entry, this, prio); } diff --git a/lib/src/phy/phch/test/pdcch_test.c b/lib/src/phy/phch/test/pdcch_test.c index e73a30d0c..93b5c299a 100644 --- a/lib/src/phy/phch/test/pdcch_test.c +++ b/lib/src/phy/phch/test/pdcch_test.c @@ -147,14 +147,16 @@ typedef struct { int main(int argc, char **argv) { srslte_pdcch_t pdcch_tx, pdcch_rx; - testcase_dci_t testcases[10] = {0}; + testcase_dci_t testcases[10] = {}; srslte_ra_dl_dci_t ra_dl; srslte_regs_t regs; int i, j, k; cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; int nof_re; cf_t *tx_slot_symbols[SRSLTE_MAX_PORTS], *rx_slot_symbols[SRSLTE_MAX_PORTS]; - int nof_dcis; + int nof_dcis; + + bzero(&testcases, sizeof(testcase_dci_t)*10); int ret = -1; diff --git a/lib/test/upper/rlc_am_stress_test.cc b/lib/test/upper/rlc_am_stress_test.cc index ad1a0c716..d6fb0882d 100644 --- a/lib/test/upper/rlc_am_stress_test.cc +++ b/lib/test/upper/rlc_am_stress_test.cc @@ -141,6 +141,7 @@ public: rlc_am_tester(rlc_interface_pdcp *rlc_){ rlc = rlc_; run_enable = true; + running = false; } void stop() diff --git a/srsenb/src/mac/scheduler.cc b/srsenb/src/mac/scheduler.cc index b7dc63898..1f1a72764 100644 --- a/srsenb/src/mac/scheduler.cc +++ b/srsenb/src/mac/scheduler.cc @@ -630,7 +630,7 @@ int sched::dl_sched_rar(dl_sched_rar_t rar[MAX_RAR_LIST]) } } else { - log_h->console("SCHED: Could not schedule DCI for RAR tti=%d, L=%d\n", pending_rar[i].rar_tti, rar_aggr_level); + log_h->warning("SCHED: Could not schedule DCI for RAR tti=%d, L=%d\n", pending_rar[i].rar_tti, rar_aggr_level); } } else { log_h->console("SCHED: Could not transmit RAR within the window (RA TTI=%d, Window=%d, Now=%d)\n", @@ -861,7 +861,7 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched aggr_level)) { h->reset(0); - printf("SCHED: Could not schedule UL DCI rnti=0x%x, pid=%d, L=%d, sf_idx=%d\n", + log_h->warning("SCHED: Could not schedule UL DCI rnti=0x%x, pid=%d, L=%d, sf_idx=%d\n", rnti, h->get_id(), aggr_level, sf_idx); sched_result->pusch[nof_dci_elems].needs_pdcch = false; From 012f026543e59730fbb323bdda7cef38942478c3 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 14 Feb 2018 10:59:54 +0000 Subject: [PATCH 46/46] Added print of UL NAS count and DL NAS count in nas_transport. --- srsepc/src/mme/s1ap_nas_transport.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 083201ff6..952d94efe 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -199,8 +199,11 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA if(*reply_flag == true) { - m_s1ap_log->info("DL NAS: Sent Downlink NAS message\n"); - m_s1ap_log->console("DL NAS: Sent Downlink NAs Message\n"); + if(ue_ctx != NULL) + { + m_s1ap_log->console("DL NAS: Sent Downlink NAs Message. DL NAS Count=%d, UL NAS Count=%d\n",ue_ctx->security_ctxt.dl_nas_count, ue_ctx->security_ctxt.ul_nas_count); + m_s1ap_log->info("DL NAS: Sent Downlink NAS message. DL NAS Count=%d, UL NAS Count=%d\n",ue_ctx->security_ctxt.dl_nas_count, ue_ctx->security_ctxt.ul_nas_count); + } } m_pool->deallocate(nas_msg);