From 724bc6cbb540d5052a0e2142b586d017fad35df1 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 23 Jan 2018 15:26:54 +0000 Subject: [PATCH 001/342] rm boost::mutex from S1AP. --- srsepc/src/mme/s1ap.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 07563e7ca..ef6a116f4 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -34,7 +34,7 @@ namespace srsepc{ s1ap* s1ap::m_instance = NULL; -boost::mutex s1ap_instance_mutex; +pthread_mutex_t s1ap_instance_mutex = PTHREAD_MUTEX_INITIALIZER; s1ap::s1ap(): m_s1mme(-1), @@ -49,21 +49,24 @@ s1ap::~s1ap() s1ap* s1ap::get_instance(void) { - boost::mutex::scoped_lock lock(s1ap_instance_mutex); - if(NULL == m_instance) { + + pthread_mutex_lock(&s1ap_instance_mutex); + if(m_instance == NULL) { m_instance = new s1ap(); } + pthread_mutex_unlock(&s1ap_instance_mutex); return(m_instance); } void s1ap::cleanup(void) { - boost::mutex::scoped_lock lock(s1ap_instance_mutex); + pthread_mutex_lock(&s1ap_instance_mutex); if(NULL != m_instance) { delete m_instance; m_instance = NULL; } + pthread_mutex_unlock(&s1ap_instance_mutex); } int From 99e1a9f0382353658aa4e775f69b6510b28731cc Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 24 Jan 2018 10:31:47 +0000 Subject: [PATCH 002/342] rm boost::mutex from MME --- srsepc/src/mme/mme.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/srsepc/src/mme/mme.cc b/srsepc/src/mme/mme.cc index ab4778c20..56766fa6b 100644 --- a/srsepc/src/mme/mme.cc +++ b/srsepc/src/mme/mme.cc @@ -29,13 +29,12 @@ #include #include #include -#include #include "mme/mme.h" namespace srsepc{ mme* mme::m_instance = NULL; -boost::mutex mme_instance_mutex; +pthread_mutex_t mme_instance_mutex = PTHREAD_MUTEX_INITIALIZER; mme::mme(): m_running(false) @@ -52,21 +51,23 @@ mme::~mme() mme* mme::get_instance(void) { - boost::mutex::scoped_lock lock(mme_instance_mutex); + pthread_mutex_lock(&mme_instance_mutex); if(NULL == m_instance) { m_instance = new mme(); } + pthread_mutex_unlock(&mme_instance_mutex); return(m_instance); } void mme::cleanup(void) { - boost::mutex::scoped_lock lock(mme_instance_mutex); + pthread_mutex_lock(&mme_instance_mutex); if(NULL != m_instance) { delete m_instance; m_instance = NULL; } + pthread_mutex_unlock(&mme_instance_mutex); } int From d87023bb37bd785b96c67bdf20dc76d622f834fb Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 24 Jan 2018 11:17:34 +0000 Subject: [PATCH 003/342] rm boost::mutex from s1ap_nas_transport --- srsepc/src/mme/s1ap_nas_transport.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index e5bf2890a..0054041fe 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -31,7 +31,7 @@ namespace srsepc{ s1ap_nas_transport* s1ap_nas_transport::m_instance = NULL; -boost::mutex s1ap_nas_transport_instance_mutex; +pthread_mutex_t s1ap_nas_transport_instance_mutex = PTHREAD_MUTEX_INITIALIZER; s1ap_nas_transport::s1ap_nas_transport() { @@ -46,21 +46,23 @@ s1ap_nas_transport::~s1ap_nas_transport() s1ap_nas_transport* s1ap_nas_transport::get_instance(void) { - boost::mutex::scoped_lock lock(s1ap_nas_transport_instance_mutex); + pthread_mutex_lock(&s1ap_nas_transport_instance_mutex); if(NULL == m_instance) { m_instance = new s1ap_nas_transport(); } + pthread_mutex_unlock(&s1ap_nas_transport_instance_mutex); return(m_instance); } void s1ap_nas_transport::cleanup(void) { - boost::mutex::scoped_lock lock(s1ap_nas_transport_instance_mutex); + pthread_mutex_lock(&s1ap_nas_transport_instance_mutex); if(NULL != m_instance) { delete m_instance; m_instance = NULL; } + pthread_mutex_unlock(&s1ap_nas_transport_instance_mutex); } void From 360bb5e2d60552bdfe08f0239eb40e9a617b30ca Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 24 Jan 2018 13:50:03 +0000 Subject: [PATCH 004/342] rm boost::mutex from s1ap_mngmnt_proc --- srsepc/src/mme/s1ap_mngmt_proc.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/srsepc/src/mme/s1ap_mngmt_proc.cc b/srsepc/src/mme/s1ap_mngmt_proc.cc index 8fa469ec3..477ce203f 100644 --- a/srsepc/src/mme/s1ap_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_mngmt_proc.cc @@ -32,7 +32,7 @@ namespace srsepc{ s1ap_mngmt_proc* s1ap_mngmt_proc::m_instance = NULL; -boost::mutex s1ap_mngmt_proc_instance_mutex; +pthread_mutex_t s1ap_mngmt_proc_instance_mutex = PTHREAD_MUTEX_INITIALIZER; s1ap_mngmt_proc::s1ap_mngmt_proc() @@ -46,21 +46,23 @@ s1ap_mngmt_proc::~s1ap_mngmt_proc() s1ap_mngmt_proc* s1ap_mngmt_proc::get_instance(void) { - boost::mutex::scoped_lock lock(s1ap_mngmt_proc_instance_mutex); + pthread_mutex_lock(&s1ap_mngmt_proc_instance_mutex); if(NULL == m_instance) { m_instance = new s1ap_mngmt_proc(); } return(m_instance); + pthread_mutex_unlock(&s1ap_mngmt_proc_instance_mutex); } void s1ap_mngmt_proc::cleanup(void) { - boost::mutex::scoped_lock lock(s1ap_mngmt_proc_instance_mutex); + pthread_mutex_lock(&s1ap_mngmt_proc_instance_mutex); if(NULL != m_instance) { delete m_instance; m_instance = NULL; } + pthread_mutex_unlock(&s1ap_mngmt_proc_instance_mutex); } void From aa437806d8218b03d4032487e61304afac327bad Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 24 Jan 2018 15:47:06 +0000 Subject: [PATCH 005/342] rm boost::mutex from s1ap_ctx_mngmt --- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 7dffe3c35..2be599c87 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -34,7 +34,7 @@ namespace srsepc{ s1ap_ctx_mngmt_proc* s1ap_ctx_mngmt_proc::m_instance = NULL; -boost::mutex s1ap_ctx_mngmt_proc_instance_mutex; +pthread_mutex_t s1ap_ctx_mngmt_proc_instance_mutex = PTHREAD_MUTEX_INITIALIZER; s1ap_ctx_mngmt_proc::s1ap_ctx_mngmt_proc() @@ -48,21 +48,23 @@ s1ap_ctx_mngmt_proc::~s1ap_ctx_mngmt_proc() s1ap_ctx_mngmt_proc* s1ap_ctx_mngmt_proc::get_instance(void) { - boost::mutex::scoped_lock lock(s1ap_ctx_mngmt_proc_instance_mutex); + pthread_mutex_lock(&s1ap_ctx_mngmt_proc_instance_mutex); if(NULL == m_instance) { m_instance = new s1ap_ctx_mngmt_proc(); } + pthread_mutex_unlock(&s1ap_ctx_mngmt_proc_instance_mutex); return(m_instance); } void s1ap_ctx_mngmt_proc::cleanup(void) { - boost::mutex::scoped_lock lock(s1ap_ctx_mngmt_proc_instance_mutex); + pthread_mutex_lock(&s1ap_ctx_mngmt_proc_instance_mutex); if(NULL != m_instance) { delete m_instance; m_instance = NULL; } + pthread_mutex_unlock(&s1ap_ctx_mngmt_proc_instance_mutex); } void From 628ccec07f3a2eeb2473c6b24509136f0288e9b9 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 24 Jan 2018 16:41:59 +0000 Subject: [PATCH 006/342] Removed boost::mutex from EPC --- srsepc/src/hss/hss.cc | 10 ++++++---- srsepc/src/mme/s1ap_mngmt_proc.cc | 2 +- srsepc/src/spgw/spgw.cc | 8 +++++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/srsepc/src/hss/hss.cc b/srsepc/src/hss/hss.cc index 5fc383078..36b47d0e3 100644 --- a/srsepc/src/hss/hss.cc +++ b/srsepc/src/hss/hss.cc @@ -36,7 +36,7 @@ using namespace srslte; namespace srsepc{ hss* hss::m_instance = NULL; -boost::mutex hss_instance_mutex; +pthread_mutex_t hss_instance_mutex = PTHREAD_MUTEX_INITIALIZER; hss::hss() // :m_sqn(0x112233445566) @@ -53,22 +53,24 @@ hss::~hss() hss* hss::get_instance(void) -{ - boost::mutex::scoped_lock lock(hss_instance_mutex); +{ + pthread_mutex_lock(&hss_instance_mutex); if(NULL == m_instance) { m_instance = new hss(); } + pthread_mutex_unlock(&hss_instance_mutex); return(m_instance); } void hss::cleanup(void) { - boost::mutex::scoped_lock lock(hss_instance_mutex); + pthread_mutex_lock(&hss_instance_mutex); if(NULL != m_instance) { delete m_instance; m_instance = NULL; } + pthread_mutex_unlock(&hss_instance_mutex); } int diff --git a/srsepc/src/mme/s1ap_mngmt_proc.cc b/srsepc/src/mme/s1ap_mngmt_proc.cc index 477ce203f..3aa3688e0 100644 --- a/srsepc/src/mme/s1ap_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_mngmt_proc.cc @@ -50,8 +50,8 @@ s1ap_mngmt_proc::get_instance(void) if(NULL == m_instance) { m_instance = new s1ap_mngmt_proc(); } - return(m_instance); pthread_mutex_unlock(&s1ap_mngmt_proc_instance_mutex); + return(m_instance); } void diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index 2458a065b..2f0e0e468 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -41,7 +41,7 @@ namespace srsepc{ spgw* spgw::m_instance = NULL; -boost::mutex spgw_instance_mutex; +pthread_mutex_t spgw_instance_mutex = PTHREAD_MUTEX_INITIALIZER; const uint16_t SPGW_BUFFER_SIZE = 2500; @@ -63,21 +63,23 @@ spgw::~spgw() spgw* spgw::get_instance(void) { - boost::mutex::scoped_lock lock(spgw_instance_mutex); + pthread_mutex_lock(&spgw_instance_mutex); if(NULL == m_instance) { m_instance = new spgw(); } + pthread_mutex_unlock(&spgw_instance_mutex); return(m_instance); } void spgw::cleanup(void) { - boost::mutex::scoped_lock lock(spgw_instance_mutex); + pthread_mutex_lock(&spgw_instance_mutex); if(NULL != m_instance) { delete m_instance; m_instance = NULL; } + pthread_mutex_unlock(&spgw_instance_mutex); } int From af2816f83fa52052f3eb93d0a7c37d384974519b Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 26 Jan 2018 17:43:21 +0000 Subject: [PATCH 007/342] Staring to make APN configurable. --- srsepc/epc.conf.example | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srsepc/epc.conf.example b/srsepc/epc.conf.example index 739b2c137..2576d127a 100644 --- a/srsepc/epc.conf.example +++ b/srsepc/epc.conf.example @@ -10,7 +10,7 @@ # tac: 16-bit Tracking Area Code. # mcc: Mobile Country Code # mnc: Mobile Network Code -# mme_bindx_addr: IP subnet to listen for eNB S1 connnections +# mme_bind_addr: IP bind addr to listen for eNB S1 connnections # ##################################################################### [mme] @@ -20,6 +20,7 @@ tac = 0x0007 mcc = 001 mnc = 01 mme_bind_addr = 127.0.1.100 +apn = srsapn ##################################################################### # HSS configuration From 7013865c0d5695b4586f802d8061a1403b26c7d2 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 30 Jan 2018 14:41:23 +0000 Subject: [PATCH 008/342] fixed un-initialized values in attach accept. --- srsepc/src/mme/s1ap_nas_transport.cc | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 0054041fe..52e8e6775 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -117,13 +117,15 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA } handle_nas_attach_request(enb_ue_s1ap_id, attach_req,pdn_con_req,reply_buffer,reply_flag, enb_sri); } + /* else if(msg_type == LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST) { m_s1ap_log->info("Received Service Request \n"); m_s1ap_log->console("Received Service Request \n"); - liblte_mme_unpack_service_request_msg((LIBLTE_BYTE_MSG_STRUCT*) nas_msg, &service_req); + liblte_mme_unpack_service_request_msg((LIBLTE_BYTE_MSG_STRUCT*) nas_msg, &service_req); + handle_nas_service_request(enb_ue_s1ap_id, attach_req,pdn_con_req,reply_buffer,reply_flag, enb_sri); return false; - } + }*/ m_pool->deallocate(nas_msg); return true; @@ -422,6 +424,18 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, return true; } + /* +bool +s1ap_nas_transport::handle_nas_service_request(uint32_t enb_ue_s1ap_id, + const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, + const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, + srslte::byte_buffer_t *reply_buffer, + bool* reply_flag, + struct sctp_sndrcvinfo *enb_sri) +{ + +}*/ + bool s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag) { @@ -1093,6 +1107,14 @@ s1ap_nas_transport::pack_attach_accept(ue_ctx_t *ue_ctx, LIBLTE_S1AP_E_RABTOBESE act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[0].contents[2] = 8; act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[0].contents[3] = 8; + //Make sure all unused options are set to false + act_def_eps_bearer_context_req.negotiated_qos_present = false; + act_def_eps_bearer_context_req.llc_sapi_present = false; + act_def_eps_bearer_context_req.radio_prio_present = false; + act_def_eps_bearer_context_req.packet_flow_id_present = false; + act_def_eps_bearer_context_req.apn_ambr_present = false; + act_def_eps_bearer_context_req.esm_cause_present = false; + uint8_t sec_hdr_type =2; ue_ctx->security_ctxt.dl_nas_count++; liblte_mme_pack_activate_default_eps_bearer_context_request_msg(&act_def_eps_bearer_context_req, &attach_accept.esm_msg); From 04188d818acdfd78b7c524a5a9ee89128fa15093 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 31 Jan 2018 15:34:01 +0100 Subject: [PATCH 009/342] disable neighbour cell measurement --- srsue/src/phy/phch_recv.cc | 5 ++++- srsue/src/phy/phch_worker.cc | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 7d89892c9..c9982b03e 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1462,6 +1462,7 @@ void phch_recv::intra_measure::rem_cell(int pci) { } void phch_recv::intra_measure::write(uint32_t tti, cf_t *data, uint32_t nsamples) { + /* if (receive_enabled) { if ((tti%INTRA_FREQ_MEAS_PERIOD_MS) == 0) { receiving = true; @@ -1482,6 +1483,7 @@ void phch_recv::intra_measure::write(uint32_t tti, cf_t *data, uint32_t nsamples } } } + */ } void phch_recv::intra_measure::run_thread() @@ -1493,13 +1495,14 @@ void phch_recv::intra_measure::run_thread() if (running) { // Read 15 ms data from buffer + /* srslte_ringbuffer_read(&ring_buffer, search_buffer, CAPTURE_LEN_SF*current_sflen*sizeof(cf_t)); int found_cells = scell.find_cells(search_buffer, common->rx_gain_offset, primary_cell, CAPTURE_LEN_SF, info); receiving = false; for (int i=0;inew_phy_meas(info[i].rsrp, info[i].rsrq, measure_tti, current_earfcn, info[i].pci); - } + }*/ // Look for other cells not found automatically } } diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 1569b0860..58da457f1 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -1388,7 +1388,7 @@ void phch_worker::update_measurements() phy->avg_rsrp_dbm = SRSLTE_VEC_EMA(rsrp_dbm, phy->avg_rsrp_dbm, snr_ema_coeff); } if ((tti%phy->pcell_report_period) == 0 && phy->pcell_meas_enabled) { - phy->rrc->new_phy_meas(phy->avg_rsrp_dbm, phy->avg_rsrq_db, tti); + //phy->rrc->new_phy_meas(phy->avg_rsrp_dbm, phy->avg_rsrq_db, tti); } } From 19129cf152313d2fd1a81fc4bd779323a68008ea Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Feb 2018 20:07:58 +0100 Subject: [PATCH 010/342] Test change SSS to Full --- lib/src/phy/sync/sync.c | 2 +- srsue/src/phy/phch_recv.cc | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/src/phy/sync/sync.c b/lib/src/phy/sync/sync.c index a49311fea..c948a53d4 100644 --- a/lib/src/phy/sync/sync.c +++ b/lib/src/phy/sync/sync.c @@ -71,7 +71,7 @@ int srslte_sync_init_decim(srslte_sync_t *q, uint32_t frame_size, uint32_t max_o q->N_id_1 = 1000; q->cfo_ema_alpha = CFO_EMA_ALPHA; - q->sss_alg = SSS_PARTIAL_3; + q->sss_alg = SSS_FULL; q->detect_cp = true; q->sss_en = true; diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 0449aaf9d..6480f8e7b 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1326,8 +1326,9 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset, for (uint32_t sf5_cnt=0;sf5_cnt max_peak && sync_res == SRSLTE_SYNC_FOUND) { best_sync_res = sync_res; From c4b2dd5e65ca48f132b4761cf421eea5e8f18033 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 2 Feb 2018 19:08:51 +0000 Subject: [PATCH 011/342] Starting to add the response to the service request. --- srsepc/hdr/mme/s1ap_nas_transport.h | 8 +++ srsepc/src/mme/s1ap.cc | 6 ++- srsepc/src/mme/s1ap_nas_transport.cc | 75 ++++++++++++++++++++++++++-- 3 files changed, 82 insertions(+), 7 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index e37ce4d61..bb8f7967f 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -47,6 +47,7 @@ public: 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); + //Initial UE messages bool handle_nas_attach_request( uint32_t enb_ue_s1ap_id, const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, @@ -65,6 +66,13 @@ public: srslte::byte_buffer_t *reply_buffer, bool* reply_flag, struct sctp_sndrcvinfo *enb_sri); + bool handle_nas_service_request(uint32_t enb_ue_s1ap_id, + const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, + const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, + srslte::byte_buffer_t *reply_buffer, + bool* reply_flag, + struct sctp_sndrcvinfo *enb_sri); + bool handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag); bool handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); bool handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 85a07596c..e0604b113 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -259,7 +259,7 @@ s1ap::handle_s1ap_rx_pdu(srslte::byte_buffer_t *pdu, struct sctp_sndrcvinfo *enb } -bool +bool s1ap::handle_initiating_message(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg, struct sctp_sndrcvinfo *enb_sri) { bool reply_flag = false; @@ -291,7 +291,9 @@ s1ap::handle_initiating_message(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg, stru ssize_t n_sent = sctp_send(m_s1mme,reply_buffer->msg, reply_buffer->N_bytes, enb_sri, 0); if(n_sent == -1) { - m_s1ap_log->console("Failed to send S1 Setup Setup Reply\n"); + m_s1ap_log->console("Failed to send S1AP Initiating Reply.\n"); + m_s1ap_log->error("Failed to send S1AP Initiating Reply. \n"); + m_pool->deallocate(reply_buffer); m_pool->deallocate(reply_buffer); return false; } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index c6f86db56..3f2a1eb49 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -117,7 +117,6 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA } handle_nas_attach_request(enb_ue_s1ap_id, attach_req,pdn_con_req,reply_buffer,reply_flag, enb_sri); } - /* else if(msg_type == LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST) { m_s1ap_log->info("Received Service Request \n"); @@ -125,7 +124,7 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA liblte_mme_unpack_service_request_msg((LIBLTE_BYTE_MSG_STRUCT*) nas_msg, &service_req); handle_nas_service_request(enb_ue_s1ap_id, attach_req,pdn_con_req,reply_buffer,reply_flag, enb_sri); return false; - }*/ + } m_pool->deallocate(nas_msg); return true; @@ -424,7 +423,6 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, return true; } - /* bool s1ap_nas_transport::handle_nas_service_request(uint32_t enb_ue_s1ap_id, const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, @@ -433,8 +431,70 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t enb_ue_s1ap_id, bool* reply_flag, struct sctp_sndrcvinfo *enb_sri) { + m_s1ap_log->warning("Service Request not handled yet\n"); + m_s1ap_log->console("Service Request not handled yet\n"); + + srslte::byte_buffer_t *nas_buffer = m_pool->allocate(); + + //Setup initiating message + LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu; + bzero(&tx_pdu, sizeof(LIBLTE_S1AP_S1AP_PDU_STRUCT)); + + tx_pdu.ext = false; + tx_pdu.choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE; + + LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *init = &tx_pdu.choice.initiatingMessage; + init->procedureCode = LIBLTE_S1AP_PROC_ID_DOWNLINKNASTRANSPORT; + init->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DOWNLINKNASTRANSPORT; + + //Setup Dw NAS structure + LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT *dw_nas = &init->choice.DownlinkNASTransport; + dw_nas->ext=false; + dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = 16; + dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = enb_ue_s1ap_id; + dw_nas->HandoverRestrictionList_present=false; + dw_nas->SubscriberProfileIDforRFP_present=false; -}*/ + LIBLTE_MME_SERVICE_REJECT_MSG_STRUCT serv_rej; + serv_rej.t3442_present = false; + serv_rej.t3446_present = false; + serv_rej.emm_cause = 9; //UE Identity cannot be derived by the network + + uint8_t sec_hdr_type = 2; + uint32_t count = 0 ; + LIBLTE_ERROR_ENUM err; + err = liblte_mme_pack_service_reject_msg(&serv_rej, sec_hdr_type, count, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); + if(err != LIBLTE_SUCCESS) + { + m_s1ap_log->error("Error packing Athentication Reject\n"); + m_s1ap_log->console("Error packing Athentication Reject\n"); + return false; + } + + //Copy NAS PDU to Downlink NAS Trasport message buffer + memcpy(dw_nas->NAS_PDU.buffer, nas_buffer->msg, nas_buffer->N_bytes); + dw_nas->NAS_PDU.n_octets = nas_buffer->N_bytes; + + //Pack Downlink NAS Transport Message + err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_buffer); + if(err != LIBLTE_SUCCESS) + { + m_s1ap_log->error("Error packing Athentication Request\n"); + m_s1ap_log->console("Error packing Athentication Request\n"); + return false; + } + + + + bool send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte::gtpc_create_session_response *cs_resp, struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid); + m_pool->deallocate(nas_buffer); + + //Send reply to eNB + *reply_flag = true; + m_s1ap_log->info("Downlink NAS: Sending Athentication Request\n"); + m_s1ap_log->console("Downlink NAS: Sending Athentication Request\n"); + return true; +} bool s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag) @@ -1063,11 +1123,16 @@ s1ap_nas_transport::pack_attach_accept(ue_ctx_t *ue_ctx, LIBLTE_S1AP_E_RABTOBESE attach_accept.guti.guti.mme_code, attach_accept.guti.guti.m_tmsi); + + attach_accept.t3402_present=true; + attach_accept.t3402.unit = LIBLTE_MME_GPRS_TIMER_UNIT_1_MINUTE; // GPRS 1 minute unit + attach_accept.t3402.value = 30; // 30 minute periodic timer + //Make sure all unused options are set to false attach_accept.lai_present=false; attach_accept.ms_id_present=false; attach_accept.emm_cause_present=false; - attach_accept.t3402_present=false; + //attach_accept.t3402_present=false; attach_accept.t3423_present=false; attach_accept.equivalent_plmns_present=false; attach_accept.emerg_num_list_present=false; From 8f206eb438d625a5edb27c499f4b71c2e7fca075 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Feb 2018 20:17:58 +0100 Subject: [PATCH 012/342] Fixed PRACH preamble when non-contention based RA --- srsue/src/mac/proc_ra.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/mac/proc_ra.cc b/srsue/src/mac/proc_ra.cc index d9a3e0d4d..f513324e9 100644 --- a/srsue/src/mac/proc_ra.cc +++ b/srsue/src/mac/proc_ra.cc @@ -222,7 +222,7 @@ void ra_proc::step_resource_selection() { if (preambleIndex > 0) { // Preamble is chosen by Higher layers (ie Network) sel_maskIndex = maskIndex; - sel_preamble = (uint32_t) preambleIndex%nof_preambles; + sel_preamble = (uint32_t) preambleIndex; } else { // Preamble is chosen by MAC UE if (!msg3_transmitted) { From 013c39abff24622de9955af05ea2fa976db6b318 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Feb 2018 20:21:38 +0100 Subject: [PATCH 013/342] Revert "Test change SSS to Full" This reverts commit 19129cf152313d2fd1a81fc4bd779323a68008ea. --- lib/src/phy/sync/sync.c | 2 +- srsue/src/phy/phch_recv.cc | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/src/phy/sync/sync.c b/lib/src/phy/sync/sync.c index c948a53d4..a49311fea 100644 --- a/lib/src/phy/sync/sync.c +++ b/lib/src/phy/sync/sync.c @@ -71,7 +71,7 @@ int srslte_sync_init_decim(srslte_sync_t *q, uint32_t frame_size, uint32_t max_o q->N_id_1 = 1000; q->cfo_ema_alpha = CFO_EMA_ALPHA; - q->sss_alg = SSS_FULL; + q->sss_alg = SSS_PARTIAL_3; q->detect_cp = true; q->sss_en = true; diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 6480f8e7b..0449aaf9d 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1326,9 +1326,8 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset, for (uint32_t sf5_cnt=0;sf5_cnt max_peak && sync_res == SRSLTE_SYNC_FOUND) { best_sync_res = sync_res; From 6ca74929a23f2a3adda221b029cd28412f5b5947 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Feb 2018 20:23:55 +0100 Subject: [PATCH 014/342] Revert "Fixed PRACH preamble when non-contention based RA" This reverts commit 8f206eb438d625a5edb27c499f4b71c2e7fca075. --- srsue/src/mac/proc_ra.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/mac/proc_ra.cc b/srsue/src/mac/proc_ra.cc index f513324e9..d9a3e0d4d 100644 --- a/srsue/src/mac/proc_ra.cc +++ b/srsue/src/mac/proc_ra.cc @@ -222,7 +222,7 @@ void ra_proc::step_resource_selection() { if (preambleIndex > 0) { // Preamble is chosen by Higher layers (ie Network) sel_maskIndex = maskIndex; - sel_preamble = (uint32_t) preambleIndex; + sel_preamble = (uint32_t) preambleIndex%nof_preambles; } else { // Preamble is chosen by MAC UE if (!msg3_transmitted) { From 955be59a594985a10af2f77ccba69ac313ed1042 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Sat, 3 Feb 2018 11:06:03 +0000 Subject: [PATCH 015/342] starting to add EMM states to keep EMM state, security context, etc., even when UE context release request is received. --- srsepc/hdr/mme/s1ap_common.h | 48 +++++++++++++++++++++++++-- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 4 +-- srsepc/src/mme/s1ap_nas_transport.cc | 28 ++++++++-------- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index f5462ad65..2d693eba9 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -33,6 +33,47 @@ static const uint8_t MAX_TA=255; //Maximum TA supported static const uint8_t MAX_BPLMN=6; //Maximum broadcasted PLMNs per TAC static const uint8_t MAX_ERABS_PER_UE = 16; +// MME EMM states (3GPP 24.301 v10.0.0, section 5.1.3.4) +typedef enum { + EMM_STATE_DEREGISTERED = 0, + EMM_STATE_COMMON_PROCEDURE_INITIATED, + EMM_STATE_REGISTERED, + EMM_STATE_DEREGISTERED_INITIATED, + EMM_STATE_N_ITEMS, +} emm_state_t; +static const char emm_state_text[EMM_STATE_N_ITEMS][100] = {"DEREGISTERED", + "COMMON PROCEDURE INITIATED", + "REGISTERED", + "DEREGISTERED INITIATED"}; + +// MME ECM states (3GPP 23.401 v10.0.0, section 4.6.3) +typedef enum { + ECM_STATE_IDLE = 0, + ECM_STATE_CONNECTED, + ECM_STATE_N_ITEMS, +} ecm_state_t; +static const char ecm_state_text[ECM_STATE_N_ITEMS][100] = {"IDLE", + "CONNECTED"}; + +// MME ESM states (3GPP 23.401 v10.0.0, section 4.6.3) +typedef enum { + ESM_BEARER_CONTEXT_INACTIVE = 0, + ESM_BEARER_CONTEXT_ACTIVE_PENDING, + ESM_BEARER_CONTEXT_ACTIVE, + ESM_BEARER_CONTEXT_INACTIVE_PENDING, + ESM_BEARER_CONTEXT_MODIFY_PENDING, + ESM_BEARER_PROCEDURE_TRANSACTION_INACTIVE, + ESM_BEARER_PROCEDURE_TRANSACTION_PENDING, + ESM_STATE_N_ITEMS, +} esm_state_t; +static const char esm_state_text[ESM_STATE_N_ITEMS][100] = {"CONTEXT INACTIVE", + "CONTEXT ACTIVE PENDING", + "CONTEXT ACTIVE", + "CONTEXT_INACTIVE_PENDING", + "CONTEXT_MODIFY_PENDING", + "PROCEDURE_TRANSACTION_INACTIVE" + "PROCEDURE_TRANSACTION_PENDING"}; + enum erab_state { ERAB_DEACTIVATED, @@ -74,6 +115,9 @@ typedef struct{ srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo; uint8_t k_nas_enc[32]; uint8_t k_nas_int[32]; + LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT ue_network_cap; + bool ms_network_cap_present; + LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT ms_network_cap; } eps_security_ctx_t; typedef struct{ @@ -89,11 +133,9 @@ typedef struct{ uint32_t mme_ue_s1ap_id; uint16_t enb_id; struct sctp_sndrcvinfo enb_sri; + emm_state_t emm_state; eps_security_ctx_t security_ctxt; erab_ctx_t erabs_ctx[MAX_ERABS_PER_UE]; - LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT ue_network_cap; - bool ms_network_cap_present; - LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT ms_network_cap; bool eit; uint8_t procedure_transaction_id; } ue_ctx_t; diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 7dffe3c35..1d6df8cf3 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -143,7 +143,7 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, bzero(in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer,sizeof(uint8_t)*16); for(int i = 0; i<3; i++) { - if(ue_ctx->ue_network_cap.eea[i+1] == true) + if(ue_ctx->security_ctxt.ue_network_cap.eea[i+1] == true) { in_ctxt_req->UESecurityCapabilities.encryptionAlgorithms.buffer[i] = 1; //EEA supported } @@ -151,7 +151,7 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, { in_ctxt_req->UESecurityCapabilities.encryptionAlgorithms.buffer[i] = 0; //EEA not supported } - if(ue_ctx->ue_network_cap.eia[i+1] == true) + if(ue_ctx->security_ctxt.ue_network_cap.eia[i+1] == true) { in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer[i] = 1; //EEA supported } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 7ba6fbe25..a200369a7 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -250,11 +250,11 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, ue_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); //Save UE network capabilities - memcpy(&ue_ctx.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT)); - ue_ctx.ms_network_cap_present = attach_req.ms_network_cap_present; + memcpy(&ue_ctx.security_ctxt.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT)); + ue_ctx.security_ctxt.ms_network_cap_present = attach_req.ms_network_cap_present; if(attach_req.ms_network_cap_present) { - memcpy(&ue_ctx.ms_network_cap, &attach_req.ms_network_cap, sizeof(LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT)); + memcpy(&ue_ctx.security_ctxt.ms_network_cap, &attach_req.ms_network_cap, sizeof(LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT)); } uint8_t eps_bearer_id = pdn_con_req.eps_bearer_id; //TODO: Unused ue_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id; @@ -345,11 +345,11 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, ue_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); //Save UE network capabilities - memcpy(&ue_ctx.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT)); - ue_ctx.ms_network_cap_present = attach_req.ms_network_cap_present; + memcpy(&ue_ctx.security_ctxt.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT)); + ue_ctx.security_ctxt.ms_network_cap_present = attach_req.ms_network_cap_present; if(attach_req.ms_network_cap_present) { - memcpy(&ue_ctx.ms_network_cap, &attach_req.ms_network_cap, sizeof(LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT)); + memcpy(&ue_ctx.security_ctxt.ms_network_cap, &attach_req.ms_network_cap, sizeof(LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT)); } uint8_t eps_bearer_id = pdn_con_req.eps_bearer_id; //TODO: Unused ue_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id; @@ -863,14 +863,14 @@ s1ap_nas_transport::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, sm_cmd.nas_ksi.nas_ksi=0; //Replay UE security cap - memcpy(sm_cmd.ue_security_cap.eea,ue_ctx->ue_network_cap.eea,8*sizeof(bool)); - memcpy(sm_cmd.ue_security_cap.eia,ue_ctx->ue_network_cap.eia,8*sizeof(bool)); - sm_cmd.ue_security_cap.uea_present = ue_ctx->ue_network_cap.uea_present; - memcpy(sm_cmd.ue_security_cap.uea,ue_ctx->ue_network_cap.uea,8*sizeof(bool)); - sm_cmd.ue_security_cap.uia_present = ue_ctx->ue_network_cap.uia_present; - memcpy(sm_cmd.ue_security_cap.uia,ue_ctx->ue_network_cap.uia,8*sizeof(bool)); - sm_cmd.ue_security_cap.gea_present = ue_ctx->ms_network_cap_present; - memcpy(sm_cmd.ue_security_cap.gea,ue_ctx->ms_network_cap.gea,8*sizeof(bool)); + memcpy(sm_cmd.ue_security_cap.eea,ue_ctx->security_ctxt.ue_network_cap.eea,8*sizeof(bool)); + memcpy(sm_cmd.ue_security_cap.eia,ue_ctx->security_ctxt.ue_network_cap.eia,8*sizeof(bool)); + sm_cmd.ue_security_cap.uea_present = ue_ctx->security_ctxt.ue_network_cap.uea_present; + memcpy(sm_cmd.ue_security_cap.uea,ue_ctx->security_ctxt.ue_network_cap.uea,8*sizeof(bool)); + sm_cmd.ue_security_cap.uia_present = ue_ctx->security_ctxt.ue_network_cap.uia_present; + memcpy(sm_cmd.ue_security_cap.uia,ue_ctx->security_ctxt.ue_network_cap.uia,8*sizeof(bool)); + sm_cmd.ue_security_cap.gea_present = ue_ctx->security_ctxt.ms_network_cap_present; + memcpy(sm_cmd.ue_security_cap.gea,ue_ctx->security_ctxt.ms_network_cap.gea,8*sizeof(bool)); sm_cmd.imeisv_req_present=false; sm_cmd.nonce_ue_present=false; From 0beb54e6969a88a7d99b7d07b48cb68268c88613 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Sat, 3 Feb 2018 17:36:57 +0000 Subject: [PATCH 016/342] Re-organized some functions. --- srsepc/src/mme/s1ap.cc | 142 ++++++++++++++++++++++------------------- 1 file changed, 75 insertions(+), 67 deletions(-) diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index a3c68bc26..03e812bba 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -88,10 +88,8 @@ s1ap::init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log) //Get pointer to the HSS m_hss = hss::get_instance(); - //Get pointer to GTP-C class m_mme_gtpc = mme_gtpc::get_instance(); - //Initialize S1-MME m_s1mme = enb_listen(); @@ -122,49 +120,9 @@ s1ap::stop() return; } -void -s1ap::delete_enb_ctx(int32_t assoc_id) -{ - std::map::iterator it_assoc = m_sctp_to_enb_id.find(assoc_id); - uint16_t enb_id = it_assoc->second; - - std::map::iterator it_ctx = m_active_enbs.find(enb_id); - if(it_ctx == m_active_enbs.end() || it_assoc == m_sctp_to_enb_id.end()) - { - m_s1ap_log->error("Could not find eNB to delete. Association: %d\n",assoc_id); - return; - } - m_s1ap_log->info("Deleting eNB context. eNB Id: 0x%x\n", enb_id); - m_s1ap_log->console("Deleting eNB context. eNB Id: 0x%x\n", enb_id); - //Delete connected UEs ctx - delete_ues_in_enb(enb_id); - - //Delete eNB - delete it_ctx->second; - m_active_enbs.erase(it_ctx); - m_sctp_to_enb_id.erase(it_assoc); - return; -} - -void -s1ap::delete_ues_in_enb(uint16_t enb_id) -{ - //delete UEs ctx - std::map >::iterator ues_in_enb = m_enb_id_to_ue_ids.find(enb_id); - std::set::iterator ue_id = ues_in_enb->second.begin(); - while(ue_id != ues_in_enb->second.end() ) - { - std::map::iterator ue_ctx = m_active_ues.find(*ue_id); - m_s1ap_log->info("Deleting UE context. UE IMSI: %lu\n", ue_ctx->second->imsi); - m_s1ap_log->console("Deleting UE context. UE IMSI: %lu\n", ue_ctx->second->imsi); - delete ue_ctx->second; //delete UE context - m_active_ues.erase(ue_ctx); //remove from general MME map - ues_in_enb->second.erase(ue_id++); //erase from the eNB's UE set - } -} int s1ap::get_s1_mme() @@ -310,6 +268,80 @@ s1ap::handle_successful_outcome(LIBLTE_S1AP_SUCCESSFULOUTCOME_STRUCT *msg) return true; } +//eNB Context Managment +void +s1ap::add_new_enb_ctx(const enb_ctx_t &enb_ctx, const struct sctp_sndrcvinfo *enb_sri) +{ + m_s1ap_log->info("Adding new eNB context. eNB ID %d\n", enb_ctx.enb_id); + std::set ue_set; + enb_ctx_t *enb_ptr = new enb_ctx_t; + memcpy(enb_ptr,&enb_ctx,sizeof(enb_ctx_t)); + m_active_enbs.insert(std::pair(enb_ptr->enb_id,enb_ptr)); + m_sctp_to_enb_id.insert(std::pair(enb_sri->sinfo_assoc_id, enb_ptr->enb_id)); + m_enb_id_to_ue_ids.insert(std::pair >(enb_ptr->enb_id,ue_set)); + + return; +} + +enb_ctx_t* +s1ap::find_enb_ctx(uint16_t enb_id) +{ + std::map::iterator it = m_active_enbs.find(enb_id); + if(it == m_active_enbs.end()) + { + return NULL; + } + else + { + return it->second; + } +} + +void +s1ap::delete_enb_ctx(int32_t assoc_id) +{ + std::map::iterator it_assoc = m_sctp_to_enb_id.find(assoc_id); + uint16_t enb_id = it_assoc->second; + + std::map::iterator it_ctx = m_active_enbs.find(enb_id); + if(it_ctx == m_active_enbs.end() || it_assoc == m_sctp_to_enb_id.end()) + { + m_s1ap_log->error("Could not find eNB to delete. Association: %d\n",assoc_id); + return; + } + + m_s1ap_log->info("Deleting eNB context. eNB Id: 0x%x\n", enb_id); + m_s1ap_log->console("Deleting eNB context. eNB Id: 0x%x\n", enb_id); + + //Delete connected UEs ctx + delete_ues_in_enb(enb_id); + + //Delete eNB + delete it_ctx->second; + m_active_enbs.erase(it_ctx); + m_sctp_to_enb_id.erase(it_assoc); + return; +} + + +//UE Context Management +void +s1ap::delete_ues_in_enb(uint16_t enb_id) +{ + //delete UEs ctx + std::map >::iterator ues_in_enb = m_enb_id_to_ue_ids.find(enb_id); + std::set::iterator ue_id = ues_in_enb->second.begin(); + while(ue_id != ues_in_enb->second.end() ) + { + std::map::iterator ue_ctx = m_active_ues.find(*ue_id); + m_s1ap_log->info("Deleting UE context. UE IMSI: %lu\n", ue_ctx->second->imsi); + m_s1ap_log->console("Deleting UE context. UE IMSI: %lu\n", ue_ctx->second->imsi); + delete ue_ctx->second; //delete UE context + m_active_ues.erase(ue_ctx); //remove from general MME map + ues_in_enb->second.erase(ue_id++); //erase from the eNB's UE set + } + +} bool s1ap::delete_ue_ctx(ue_ctx_t *ue_ctx) @@ -346,33 +378,9 @@ s1ap::delete_ue_ctx(ue_ctx_t *ue_ctx) return true; } -enb_ctx_t* -s1ap::find_enb_ctx(uint16_t enb_id) -{ - std::map::iterator it = m_active_enbs.find(enb_id); - if(it == m_active_enbs.end()) - { - return NULL; - } - else - { - return it->second; - } -} -void -s1ap::add_new_enb_ctx(const enb_ctx_t &enb_ctx, const struct sctp_sndrcvinfo *enb_sri) -{ - m_s1ap_log->info("Adding new eNB context. eNB ID %d\n", enb_ctx.enb_id); - std::set ue_set; - enb_ctx_t *enb_ptr = new enb_ctx_t; - memcpy(enb_ptr,&enb_ctx,sizeof(enb_ctx_t)); - m_active_enbs.insert(std::pair(enb_ptr->enb_id,enb_ptr)); - m_sctp_to_enb_id.insert(std::pair(enb_sri->sinfo_assoc_id, enb_ptr->enb_id)); - m_enb_id_to_ue_ids.insert(std::pair >(enb_ptr->enb_id,ue_set)); - return; -} + ue_ctx_t* s1ap::find_ue_ctx(uint32_t mme_ue_s1ap_id) From cc9e1294c635d70cc9f60c7d7805af9b556b96b1 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 5 Feb 2018 10:46:57 +0000 Subject: [PATCH 017/342] re-organized some functions. --- srsepc/src/mme/s1ap.cc | 64 ++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 03e812bba..d91b4c4c5 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -325,6 +325,39 @@ s1ap::delete_enb_ctx(int32_t assoc_id) //UE Context Management +void +s1ap::add_new_ue_ctx(const ue_ctx_t &ue_ctx) +{ + ue_ctx_t *ue_ptr = new ue_ctx_t; + memcpy(ue_ptr,&ue_ctx,sizeof(ue_ctx)); + m_active_ues.insert(std::pair(ue_ptr->mme_ue_s1ap_id,ue_ptr)); + + std::map::iterator it_enb = m_sctp_to_enb_id.find(ue_ptr->enb_sri.sinfo_assoc_id); + uint16_t enb_id = it_enb->second; + std::map >::iterator it_ue_id = m_enb_id_to_ue_ids.find(enb_id); + if(it_ue_id==m_enb_id_to_ue_ids.end()) + { + m_s1ap_log->error("Could not find eNB's UEs\n"); + return; + } + it_ue_id->second.insert(ue_ptr->mme_ue_s1ap_id); + return; +} + +ue_ctx_t* +s1ap::find_ue_ctx(uint32_t mme_ue_s1ap_id) +{ + std::map::iterator it = m_active_ues.find(mme_ue_s1ap_id); + if(it == m_active_ues.end()) + { + return NULL; + } + else + { + return it->second; + } +} + void s1ap::delete_ues_in_enb(uint16_t enb_id) { @@ -382,38 +415,7 @@ s1ap::delete_ue_ctx(ue_ctx_t *ue_ctx) -ue_ctx_t* -s1ap::find_ue_ctx(uint32_t mme_ue_s1ap_id) -{ - std::map::iterator it = m_active_ues.find(mme_ue_s1ap_id); - if(it == m_active_ues.end()) - { - return NULL; - } - else - { - return it->second; - } -} -void -s1ap::add_new_ue_ctx(const ue_ctx_t &ue_ctx) -{ - ue_ctx_t *ue_ptr = new ue_ctx_t; - memcpy(ue_ptr,&ue_ctx,sizeof(ue_ctx)); - m_active_ues.insert(std::pair(ue_ptr->mme_ue_s1ap_id,ue_ptr)); - - std::map::iterator it_enb = m_sctp_to_enb_id.find(ue_ptr->enb_sri.sinfo_assoc_id); - uint16_t enb_id = it_enb->second; - std::map >::iterator it_ue_id = m_enb_id_to_ue_ids.find(enb_id); - if(it_ue_id==m_enb_id_to_ue_ids.end()) - { - m_s1ap_log->error("Could not find eNB's UEs\n"); - return; - } - it_ue_id->second.insert(ue_ptr->mme_ue_s1ap_id); - return; -} uint32_t s1ap::get_next_mme_ue_s1ap_id() From 336af1ed93da8489305349b09bba439761cd16ad Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 5 Feb 2018 12:26:23 +0000 Subject: [PATCH 018/342] Adding functions to get context from IMSI or MME UE S1AP Id. --- srsepc/hdr/mme/s1ap.h | 7 +++-- srsepc/src/mme/s1ap.cc | 65 +++++++++++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 16 deletions(-) diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index fc4dd3d49..0f4be8d9b 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -81,6 +81,8 @@ public: void add_new_enb_ctx(const enb_ctx_t &enb_ctx, const struct sctp_sndrcvinfo* enb_sri); ue_ctx_t* find_ue_ctx(uint32_t mme_ue_s1ap_id); void add_new_ue_ctx(const ue_ctx_t &ue_ctx); + ue_ctx_t* find_ue_ctx_from_imsi(uint64_t imsi); + ue_ctx_t* find_ue_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id); bool delete_ue_ctx(ue_ctx_t *ue_ctx); uint32_t allocate_m_tmsi(uint32_t mme_ue_s1ap_id); @@ -107,12 +109,13 @@ private: int m_s1mme; std::map m_active_enbs; std::map m_sctp_to_enb_id; - std::map m_active_ues; + std::map m_imsi_to_ue_ctx; + std::map m_mme_ue_s1ap_id_to_imsi; std::map > m_enb_id_to_ue_ids; uint32_t m_next_mme_ue_s1ap_id; uint32_t m_next_m_tmsi; - //FIXME the GTP-C should be moved to the MME class, the the packaging of GTP-C messages is done. + //FIXME the GTP-C should be moved to the MME class, when the packaging of GTP-C messages is done. mme_gtpc *m_mme_gtpc; }; diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index d91b4c4c5..877912e8d 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -120,16 +120,19 @@ s1ap::stop() return; } - - - - int s1ap::get_s1_mme() { return m_s1mme; } +uint32_t +s1ap::get_next_mme_ue_s1ap_id() +{ + return m_next_mme_ue_s1ap_id++; +} + + int s1ap::enb_listen() { @@ -246,7 +249,7 @@ s1ap::handle_initiating_message(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg, stru ssize_t n_sent = sctp_send(m_s1mme,reply_buffer->msg, reply_buffer->N_bytes, enb_sri, 0); if(n_sent == -1) { - m_s1ap_log->console("Failed to send S1 Setup Setup Reply\n"); + m_s1ap_log->console("Failed to send S1AP Initiating Message Reply\n"); m_pool->deallocate(reply_buffer); return false; } @@ -327,6 +330,31 @@ s1ap::delete_enb_ctx(int32_t assoc_id) //UE Context Management void s1ap::add_new_ue_ctx(const ue_ctx_t &ue_ctx) +{ + ue_ctx_t *ue_ptr = new ue_ctx_t; + memcpy(ue_ptr,&ue_ctx,sizeof(ue_ctx)); + + //This map will store the context of previously registered UEs + m_imsi_to_ue_ctx.insert(std::pair(ue_ptr->imsi,ue_ptr)); + + //This will map UE's MME S1AP Id to the UE's IMSI, when they are not in the EMM-DERGISTERED state. + m_mme_ue_s1ap_id_to_imsi.insert(std::pair(ue_ptr->mme_ue_s1ap_id,ue_ptr->imsi)); + + //Store which enb currently holds the UE + std::map::iterator it_enb = m_sctp_to_enb_id.find(ue_ptr->enb_sri.sinfo_assoc_id); + uint16_t enb_id = it_enb->second; + std::map >::iterator it_ue_id = m_enb_id_to_ue_ids.find(enb_id); + if(it_ue_id==m_enb_id_to_ue_ids.end()) + { + m_s1ap_log->error("Could not find eNB's UEs\n"); + return; + } + it_ue_id->second.insert(ue_ptr->mme_ue_s1ap_id); + +} + /* +void +s1ap::add_new_ue_ctx(const ue_ctx_t &ue_ctx) { ue_ctx_t *ue_ptr = new ue_ctx_t; memcpy(ue_ptr,&ue_ctx,sizeof(ue_ctx)); @@ -343,12 +371,12 @@ s1ap::add_new_ue_ctx(const ue_ctx_t &ue_ctx) it_ue_id->second.insert(ue_ptr->mme_ue_s1ap_id); return; } - + */ ue_ctx_t* -s1ap::find_ue_ctx(uint32_t mme_ue_s1ap_id) +s1ap::find_ue_ctx_from_imsi(uint64_t imsi) { - std::map::iterator it = m_active_ues.find(mme_ue_s1ap_id); - if(it == m_active_ues.end()) + std::map::iterator it = m_imsi_to_ue_ctx.find(imsi); + if(it == m_imsi_to_ue_ctx.end()) { return NULL; } @@ -358,6 +386,19 @@ s1ap::find_ue_ctx(uint32_t mme_ue_s1ap_id) } } +ue_ctx_t* +s1ap::find_ue_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id) +{ + std::map::iterator imsi_it = m_mme_ue_s1ap_id_to_imsi.find(mme_ue_s1ap_id); + if(imsi_it == m_mme_ue_s1ap_id_to_imsi.find(mme_ue_s1ap_id)) + { + return NULL; + } + else + { + return find_ue_ctx_from_imsi(imsi_it->second); + } +} void s1ap::delete_ues_in_enb(uint16_t enb_id) { @@ -417,11 +458,7 @@ s1ap::delete_ue_ctx(ue_ctx_t *ue_ctx) -uint32_t -s1ap::get_next_mme_ue_s1ap_id() -{ - return m_next_mme_ue_s1ap_id++; -} + void s1ap::activate_eps_bearer(uint32_t mme_s1ap_id, uint8_t ebi) From a0d727166ff5007db9c8b88695ff7ada1617e80e Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 5 Feb 2018 13:11:03 +0000 Subject: [PATCH 019/342] Starting to split EMM and ECM context. --- srsepc/hdr/mme/s1ap_common.h | 19 +++++++++++++ srsepc/src/mme/s1ap.cc | 55 ++++++++++++++++++++++++------------ 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index 2d693eba9..b252df586 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -127,6 +127,25 @@ typedef struct{ srslte::gtpc_f_teid_ie sgw_ctrl_fteid; } erab_ctx_t; +typedef struct{ + uint64_t imsi; + LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT guti; + emm_state_t emm_state; + eps_security_ctx_t security_ctxt; + uint8_t procedure_transaction_id; +} ue_emm_ctx_t; + +typedef struct{ + uint32_t enb_ue_s1ap_id; + uint32_t mme_ue_s1ap_id; + uint16_t enb_id; + struct sctp_sndrcvinfo enb_sri; + ecm_state_t ecm_state; + bool eit; + erab_ctx_t erabs_ctx[MAX_ERABS_PER_UE]; +} ue_esm_ctx_t; + + typedef struct{ uint64_t imsi; uint32_t enb_ue_s1ap_id; diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 877912e8d..0db79a8fb 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -399,26 +399,9 @@ s1ap::find_ue_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id) return find_ue_ctx_from_imsi(imsi_it->second); } } -void -s1ap::delete_ues_in_enb(uint16_t enb_id) -{ - //delete UEs ctx - std::map >::iterator ues_in_enb = m_enb_id_to_ue_ids.find(enb_id); - std::set::iterator ue_id = ues_in_enb->second.begin(); - while(ue_id != ues_in_enb->second.end() ) - { - std::map::iterator ue_ctx = m_active_ues.find(*ue_id); - m_s1ap_log->info("Deleting UE context. UE IMSI: %lu\n", ue_ctx->second->imsi); - m_s1ap_log->console("Deleting UE context. UE IMSI: %lu\n", ue_ctx->second->imsi); - delete ue_ctx->second; //delete UE context - m_active_ues.erase(ue_ctx); //remove from general MME map - ues_in_enb->second.erase(ue_id++); //erase from the eNB's UE set - } - -} bool -s1ap::delete_ue_ctx(ue_ctx_t *ue_ctx) +s1ap::delete_ue_esm_ctx(uint32_t mme_ue_s1ap_id) { uint32_t mme_ue_s1ap_id = ue_ctx->mme_ue_s1ap_id; std::map::iterator ue_ctx_it = m_active_ues.find(mme_ue_s1ap_id); @@ -451,6 +434,42 @@ s1ap::delete_ue_ctx(ue_ctx_t *ue_ctx) return true; } +void +s1ap::delete_ues_esm_ctx_in_enb(uint16_t enb_id) +{ + //delete UEs ctx + std::map >::iterator ues_in_enb = m_enb_id_to_ue_ids.find(enb_id); + std::set::iterator ue_id = ues_in_enb->second.begin(); + while(ue_id != ues_in_enb->second.end() ) + { + std::map::iterator ue_ctx = m_active_ues.find(*ue_id); + m_s1ap_log->info("Deleting UE context. UE IMSI: %lu\n", ue_ctx->second->imsi); + m_s1ap_log->console("Deleting UE context. UE IMSI: %lu\n", ue_ctx->second->imsi); + delete ue_ctx->second; //delete UE context + m_active_ues.erase(ue_ctx); //remove from general MME map + ues_in_enb->second.erase(ue_id++); //erase from the eNB's UE set + } +} + +void +s1ap::delete_ues_in_enb(uint16_t enb_id) +{ + //delete UEs ctx + std::map >::iterator ues_in_enb = m_enb_id_to_ue_ids.find(enb_id); + std::set::iterator ue_id = ues_in_enb->second.begin(); + while(ue_id != ues_in_enb->second.end() ) + { + std::map::iterator ue_ctx = m_active_ues.find(*ue_id); + m_s1ap_log->info("Deleting UE context. UE IMSI: %lu\n", ue_ctx->second->imsi); + m_s1ap_log->console("Deleting UE context. UE IMSI: %lu\n", ue_ctx->second->imsi); + delete ue_ctx->second; //delete UE context + m_active_ues.erase(ue_ctx); //remove from general MME map + ues_in_enb->second.erase(ue_id++); //erase from the eNB's UE set + } + +} + + From d9da1f84f01244b0a66ccadf65c9c61fe67e1c87 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 5 Feb 2018 15:33:16 +0000 Subject: [PATCH 020/342] Continuing to separate EMM and ECM context --- srsepc/hdr/mme/s1ap.h | 18 ++++-- srsepc/hdr/mme/s1ap_common.h | 2 +- srsepc/src/mme/s1ap.cc | 112 ++++++++++++++++++----------------- 3 files changed, 73 insertions(+), 59 deletions(-) diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 0f4be8d9b..9e23868e8 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -79,11 +79,17 @@ public: uint32_t get_next_mme_ue_s1ap_id(); enb_ctx_t* find_enb_ctx(uint16_t enb_id); void add_new_enb_ctx(const enb_ctx_t &enb_ctx, const struct sctp_sndrcvinfo* enb_sri); + ue_ctx_t* find_ue_ctx(uint32_t mme_ue_s1ap_id); void add_new_ue_ctx(const ue_ctx_t &ue_ctx); - ue_ctx_t* find_ue_ctx_from_imsi(uint64_t imsi); - ue_ctx_t* find_ue_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id); - bool delete_ue_ctx(ue_ctx_t *ue_ctx); + + void add_new_ue_emm_ctx(const ue_emm_ctx_t &ue_emm_ctx); + void add_new_ue_ecm_ctx(const ue_ecm_ctx_t &ue_ecm_ctx); + ue_emm_ctx_t* find_ue_emm_ctx_from_imsi(uint64_t imsi); + ue_ecm_ctx_t* find_ue_ecm_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id); + bool delete_ue_emm_ctx(ue_emm_ctx_t *ue_emm_ctx); + bool delete_ue_ecm_ctx(uint32_t mme_ue_s1ap_id); + void delete_ues_ecm_ctx_in_enb(uint16_t enb_id); uint32_t allocate_m_tmsi(uint32_t mme_ue_s1ap_id); @@ -109,9 +115,11 @@ private: int m_s1mme; std::map m_active_enbs; std::map m_sctp_to_enb_id; - std::map m_imsi_to_ue_ctx; - std::map m_mme_ue_s1ap_id_to_imsi; std::map > m_enb_id_to_ue_ids; + + std::map m_imsi_to_ue_emm_ctx; + std::map m_mme_ue_s1ap_id_to_ue_ecm_ctx; + uint32_t m_next_mme_ue_s1ap_id; uint32_t m_next_m_tmsi; diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index b252df586..7a76f7eb9 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -143,7 +143,7 @@ typedef struct{ ecm_state_t ecm_state; bool eit; erab_ctx_t erabs_ctx[MAX_ERABS_PER_UE]; -} ue_esm_ctx_t; +} ue_ecm_ctx_t; typedef struct{ diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 0db79a8fb..0b2379571 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -328,6 +328,38 @@ s1ap::delete_enb_ctx(int32_t assoc_id) //UE Context Management + +void +s1ap::add_new_ue_emm_ctx(const ue_emm_ctx_t &ue_emm_ctx) +{ + ue_emm_ctx_t *ue_ptr = new ue_emm_ctx_t; + memcpy(ue_ptr,&ue_emm_ctx,sizeof(ue_emm_ctx)); + + //This map will store UEs EMM context + m_imsi_to_ue_emm_ctx.insert(std::pair(ue_ptr->imsi,ue_ptr)); +} + +void +s1ap::add_new_ue_ecm_ctx(const ue_ecm_ctx_t &ue_ecm_ctx) +{ + ue_ecm_ctx_t *ue_ptr = new ue_ecm_ctx_t; + memcpy(ue_ptr,&ue_ecm_ctx,sizeof(ue_ecm_ctx)); + + //This map will store UE's ECM context. + m_mme_ue_s1ap_id_to_ue_ecm_ctx.insert(std::pair(ue_ptr->mme_ue_s1ap_id,ue_ptr)); + //Store which enb currently holds the UE + std::map::iterator it_enb = m_sctp_to_enb_id.find(ue_ptr->enb_sri.sinfo_assoc_id); + uint16_t enb_id = it_enb->second; + std::map >::iterator it_ue_id = m_enb_id_to_ue_ids.find(enb_id); + if(it_ue_id==m_enb_id_to_ue_ids.end()) + { + m_s1ap_log->error("Could not find eNB's UEs\n"); + return; + } + it_ue_id->second.insert(ue_ptr->mme_ue_s1ap_id); +} + + /* void s1ap::add_new_ue_ctx(const ue_ctx_t &ue_ctx) { @@ -351,7 +383,7 @@ s1ap::add_new_ue_ctx(const ue_ctx_t &ue_ctx) } it_ue_id->second.insert(ue_ptr->mme_ue_s1ap_id); -} +}*/ /* void s1ap::add_new_ue_ctx(const ue_ctx_t &ue_ctx) @@ -372,11 +404,11 @@ s1ap::add_new_ue_ctx(const ue_ctx_t &ue_ctx) return; } */ -ue_ctx_t* -s1ap::find_ue_ctx_from_imsi(uint64_t imsi) +ue_emm_ctx_t* +s1ap::find_ue_emm_ctx_from_imsi(uint64_t imsi) { - std::map::iterator it = m_imsi_to_ue_ctx.find(imsi); - if(it == m_imsi_to_ue_ctx.end()) + std::map::iterator it = m_imsi_to_ue_emm_ctx.find(imsi); + if(it == m_imsi_to_ue_emm_ctx.end()) { return NULL; } @@ -386,33 +418,33 @@ s1ap::find_ue_ctx_from_imsi(uint64_t imsi) } } -ue_ctx_t* -s1ap::find_ue_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id) +ue_ecm_ctx_t* +s1ap::find_ue_ecm_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id) { - std::map::iterator imsi_it = m_mme_ue_s1ap_id_to_imsi.find(mme_ue_s1ap_id); - if(imsi_it == m_mme_ue_s1ap_id_to_imsi.find(mme_ue_s1ap_id)) + std::map::iterator it = m_mme_ue_s1ap_id_to_ue_ecm_ctx.find(mme_ue_s1ap_id); + if(it == m_mme_ue_s1ap_id_to_ue_ecm_ctx.end()) { return NULL; } else { - return find_ue_ctx_from_imsi(imsi_it->second); + return it->second; } } bool -s1ap::delete_ue_esm_ctx(uint32_t mme_ue_s1ap_id) +s1ap::delete_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) { - uint32_t mme_ue_s1ap_id = ue_ctx->mme_ue_s1ap_id; - std::map::iterator ue_ctx_it = m_active_ues.find(mme_ue_s1ap_id); - if(ue_ctx_it == m_active_ues.end() ) + std::map::iterator ue_ecm_ctx_it = m_mme_ue_s1ap_id_to_ue_ecm_ctx.find(mme_ue_s1ap_id); + if(ue_ecm_ctx_it == m_mme_ue_s1ap_id_to_ue_ecm_ctx.end()) { - m_s1ap_log->info("UE not found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); + m_s1ap_log->info("Cannot delete UE ECM context, UE not found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); return false; } + ue_ecm_ctx_t* ue_ecm_ctx = ue_ecm_ctx_it->second; //Delete UE within eNB UE set - std::map::iterator it = m_sctp_to_enb_id.find(ue_ctx->enb_sri.sinfo_assoc_id); + std::map::iterator it = m_sctp_to_enb_id.find(ue_ecm_ctx->enb_sri.sinfo_assoc_id); if(it == m_sctp_to_enb_id.end() ) { m_s1ap_log->error("Could not find eNB for this request.\n"); @@ -428,67 +460,41 @@ s1ap::delete_ue_esm_ctx(uint32_t mme_ue_s1ap_id) ue_set->second.erase(mme_ue_s1ap_id); //Delete UE context - delete ue_ctx; - m_active_ues.erase(ue_ctx_it); + m_mme_ue_s1ap_id_to_ue_ecm_ctx.erase(ue_ecm_ctx_it); + delete ue_ecm_ctx; m_s1ap_log->info("Deleted UE Context.\n"); return true; } -void -s1ap::delete_ues_esm_ctx_in_enb(uint16_t enb_id) -{ - //delete UEs ctx - std::map >::iterator ues_in_enb = m_enb_id_to_ue_ids.find(enb_id); - std::set::iterator ue_id = ues_in_enb->second.begin(); - while(ue_id != ues_in_enb->second.end() ) - { - std::map::iterator ue_ctx = m_active_ues.find(*ue_id); - m_s1ap_log->info("Deleting UE context. UE IMSI: %lu\n", ue_ctx->second->imsi); - m_s1ap_log->console("Deleting UE context. UE IMSI: %lu\n", ue_ctx->second->imsi); - delete ue_ctx->second; //delete UE context - m_active_ues.erase(ue_ctx); //remove from general MME map - ues_in_enb->second.erase(ue_id++); //erase from the eNB's UE set - } -} void -s1ap::delete_ues_in_enb(uint16_t enb_id) +s1ap::delete_ues_ecm_ctx_in_enb(uint16_t enb_id) { //delete UEs ctx std::map >::iterator ues_in_enb = m_enb_id_to_ue_ids.find(enb_id); std::set::iterator ue_id = ues_in_enb->second.begin(); while(ue_id != ues_in_enb->second.end() ) { - std::map::iterator ue_ctx = m_active_ues.find(*ue_id); - m_s1ap_log->info("Deleting UE context. UE IMSI: %lu\n", ue_ctx->second->imsi); - m_s1ap_log->console("Deleting UE context. UE IMSI: %lu\n", ue_ctx->second->imsi); + std::map::iterator ue_ctx = m_mme_ue_s1ap_id_to_ue_ecm_ctx.find(*ue_id); + m_s1ap_log->info("Deleting UE context. UE-MME S1AP Id: %d\n", ue_ctx->second->mme_ue_s1ap_id); + m_s1ap_log->console("Deleting UE context. UE-MME S1AP Id: %d\n", ue_ctx->second->mme_ue_s1ap_id); + m_mme_ue_s1ap_id_to_ue_ecm_ctx.erase(ue_ctx); //remove from general MME map delete ue_ctx->second; //delete UE context - m_active_ues.erase(ue_ctx); //remove from general MME map ues_in_enb->second.erase(ue_id++); //erase from the eNB's UE set } - } - - - - - - - - - - +//UE Bearer Managment void s1ap::activate_eps_bearer(uint32_t mme_s1ap_id, uint8_t ebi) { - std::map::iterator ue_ctx_it = m_active_ues.find(mme_s1ap_id); - if(ue_ctx_it == m_active_ues.end()) + std::map::iterator ue_ctx_it = m_mme_ue_s1ap_id_to_ue_ecm_ctx.find(mme_s1ap_id); + if(ue_ctx_it == m_mme_ue_s1ap_id_to_ue_ecm_ctx.end()) { m_s1ap_log->error("Could not find UE context\n"); return; } - ue_ctx_t * ue_ctx = ue_ctx_it->second; + ue_ecm_ctx_t * ue_ctx = ue_ctx_it->second; if (ue_ctx->erabs_ctx[ebi].state != ERAB_CTX_SETUP) { m_s1ap_log->error("EPS Bearer could not be activated. MME S1AP Id %d, EPS Bearer id %d, state %d\n",mme_s1ap_id,ebi,ue_ctx->erabs_ctx[ebi].state); From 085830d9107df225121a7f2048cc8ece6242b712 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 5 Feb 2018 15:55:41 +0000 Subject: [PATCH 021/342] Changing delete functions to delete both EMM and ECM context. --- srsepc/src/mme/s1ap.cc | 69 ++++++++++-------------------------------- 1 file changed, 16 insertions(+), 53 deletions(-) diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 0b2379571..d421191d5 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -103,16 +103,24 @@ s1ap::stop() if (m_s1mme != -1){ close(m_s1mme); } - std::map::iterator it = m_active_enbs.begin(); - while(it!=m_active_enbs.end()) + std::map::iterator enb_it = m_active_enbs.begin(); + while(enb_it!=m_active_enbs.end()) { - m_s1ap_log->info("Deleting eNB context. eNB Id: 0x%x\n", it->second->enb_id); - m_s1ap_log->console("Deleting eNB context. eNB Id: 0x%x\n", it->second->enb_id); - delete_ues_in_enb(it->second->enb_id); - delete it->second; - m_active_enbs.erase(it++); + m_s1ap_log->info("Deleting eNB context. eNB Id: 0x%x\n", enb_it->second->enb_id); + m_s1ap_log->console("Deleting eNB context. eNB Id: 0x%x\n", enb_it->second->enb_id); + delete_ues_ecm_ctx_in_enb(enb_it->second->enb_id); + delete enb_it->second; + m_active_enbs.erase(enb_it++); } + std::map::iterator ue_it = m_imsi_to_ue_emm_ctx.begin(); + while(ue_it!=m_imsi_to_ue_emm_ctx.end()) + { + m_s1ap_log->info("Deleting UE EMM context. IMSI: %015lu\n", ue_it->first); + m_s1ap_log->console("Deleting UE EMM context. IMSI: %015lu\n", ue_it->first); + delete ue_it->second; + m_imsi_to_ue_emm_ctx.erase(ue_it++); + } //Cleanup message handlers s1ap_mngmt_proc::cleanup(); s1ap_nas_transport::cleanup(); @@ -317,7 +325,7 @@ s1ap::delete_enb_ctx(int32_t assoc_id) m_s1ap_log->console("Deleting eNB context. eNB Id: 0x%x\n", enb_id); //Delete connected UEs ctx - delete_ues_in_enb(enb_id); + delete_ues_ecm_ctx_in_enb(enb_id); //Delete eNB delete it_ctx->second; @@ -328,7 +336,6 @@ s1ap::delete_enb_ctx(int32_t assoc_id) //UE Context Management - void s1ap::add_new_ue_emm_ctx(const ue_emm_ctx_t &ue_emm_ctx) { @@ -359,51 +366,7 @@ s1ap::add_new_ue_ecm_ctx(const ue_ecm_ctx_t &ue_ecm_ctx) it_ue_id->second.insert(ue_ptr->mme_ue_s1ap_id); } - /* -void -s1ap::add_new_ue_ctx(const ue_ctx_t &ue_ctx) -{ - ue_ctx_t *ue_ptr = new ue_ctx_t; - memcpy(ue_ptr,&ue_ctx,sizeof(ue_ctx)); - - //This map will store the context of previously registered UEs - m_imsi_to_ue_ctx.insert(std::pair(ue_ptr->imsi,ue_ptr)); - - //This will map UE's MME S1AP Id to the UE's IMSI, when they are not in the EMM-DERGISTERED state. - m_mme_ue_s1ap_id_to_imsi.insert(std::pair(ue_ptr->mme_ue_s1ap_id,ue_ptr->imsi)); - - //Store which enb currently holds the UE - std::map::iterator it_enb = m_sctp_to_enb_id.find(ue_ptr->enb_sri.sinfo_assoc_id); - uint16_t enb_id = it_enb->second; - std::map >::iterator it_ue_id = m_enb_id_to_ue_ids.find(enb_id); - if(it_ue_id==m_enb_id_to_ue_ids.end()) - { - m_s1ap_log->error("Could not find eNB's UEs\n"); - return; - } - it_ue_id->second.insert(ue_ptr->mme_ue_s1ap_id); - -}*/ - /* -void -s1ap::add_new_ue_ctx(const ue_ctx_t &ue_ctx) -{ - ue_ctx_t *ue_ptr = new ue_ctx_t; - memcpy(ue_ptr,&ue_ctx,sizeof(ue_ctx)); - m_active_ues.insert(std::pair(ue_ptr->mme_ue_s1ap_id,ue_ptr)); - std::map::iterator it_enb = m_sctp_to_enb_id.find(ue_ptr->enb_sri.sinfo_assoc_id); - uint16_t enb_id = it_enb->second; - std::map >::iterator it_ue_id = m_enb_id_to_ue_ids.find(enb_id); - if(it_ue_id==m_enb_id_to_ue_ids.end()) - { - m_s1ap_log->error("Could not find eNB's UEs\n"); - return; - } - it_ue_id->second.insert(ue_ptr->mme_ue_s1ap_id); - return; -} - */ ue_emm_ctx_t* s1ap::find_ue_emm_ctx_from_imsi(uint64_t imsi) { From 1df3f0419260cefabbbdc3fe91207865772eb384 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 5 Feb 2018 18:06:19 +0000 Subject: [PATCH 022/342] Changing handle nas security mode complete. --- srsepc/hdr/mme/s1ap_common.h | 1 + srsepc/hdr/mme/s1ap_nas_transport.h | 16 ++--- srsepc/src/mme/s1ap_nas_transport.cc | 101 +++++++++++++++------------ 3 files changed, 67 insertions(+), 51 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index 7a76f7eb9..bf07a7c70 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -136,6 +136,7 @@ typedef struct{ } ue_emm_ctx_t; typedef struct{ + uint64_t imsi; uint32_t enb_ue_s1ap_id; uint32_t mme_ue_s1ap_id; uint16_t enb_id; diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index e37ce4d61..3e897c0a4 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -65,19 +65,19 @@ public: srslte::byte_buffer_t *reply_buffer, bool* reply_flag, struct sctp_sndrcvinfo *enb_sri); - bool handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag); - bool handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); - bool handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); - 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_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag); + bool handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); + bool handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); + bool handle_esm_information_response(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag); + bool handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag); + bool handle_tracking_area_update_request(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_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); - bool pack_security_mode_command(srslte::byte_buffer_t *reply_msg, ue_ctx_t *ue_ctx); - bool pack_esm_information_request(srslte::byte_buffer_t *reply_msg, ue_ctx_t *ue_ctx); + bool pack_security_mode_command(srslte::byte_buffer_t *reply_msg, ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *ue_ecm_ctx); + bool pack_esm_information_request(srslte::byte_buffer_t *reply_msg, ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *ue_ecm_ctx); bool pack_attach_accept(ue_ctx_t *ue_ctx, LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *erab_ctxt, struct srslte::gtpc_pdn_address_allocation_ie *paa, srslte::byte_buffer_t *nas_buffer); bool pack_identity_request(srslte::byte_buffer_t *reply_msg, uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index a200369a7..ae84b328b 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -135,14 +135,12 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA uint32_t enb_ue_s1ap_id = ul_xport->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID; uint32_t mme_ue_s1ap_id = ul_xport->MME_UE_S1AP_ID.MME_UE_S1AP_ID; - ue_ctx_t *ue_ctx = m_s1ap->find_ue_ctx(mme_ue_s1ap_id); - if(ue_ctx == NULL) + ue_ecm_ctx_t *ue_ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); + if(ue_ecm_ctx == NULL) { - //TODO UE not registered, send error message. - m_s1ap_log->warning("Received uplink NAS, but could not find UE context. MME-UE S1AP id: %lu\n",mme_ue_s1ap_id); + m_s1ap_log->warning("Received uplink NAS, but could not find UE ECM context. MME-UE S1AP id: %lu\n",mme_ue_s1ap_id); return false; } - m_s1ap_log->debug("Received uplink NAS and found UE. MME-UE S1AP id: %lu\n",mme_ue_s1ap_id); //Get NAS message type @@ -157,39 +155,37 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE: m_s1ap_log->info("Uplink NAS: Received Authentication Response\n"); m_s1ap_log->console("Uplink NAS: Received Authentication Response\n"); - handle_nas_authentication_response(nas_msg, ue_ctx, reply_buffer, reply_flag); + handle_nas_authentication_response(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); break; case LIBLTE_MME_MSG_TYPE_SECURITY_MODE_COMPLETE: m_s1ap_log->info("Uplink NAS: Received Security Mode Complete\n"); m_s1ap_log->console("Uplink NAS: Received Security Mode Complete\n"); - handle_nas_security_mode_complete(nas_msg, ue_ctx, reply_buffer, reply_flag); + handle_nas_security_mode_complete(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); break; case LIBLTE_MME_MSG_TYPE_ATTACH_COMPLETE: m_s1ap_log->info("Uplink NAS: Received Attach Complete\n"); m_s1ap_log->console("Uplink NAS: Received Attach Complete\n"); - handle_nas_attach_complete(nas_msg, ue_ctx, reply_buffer, reply_flag); - ue_ctx->security_ctxt.ul_nas_count++; + handle_nas_attach_complete(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); break; case LIBLTE_MME_MSG_TYPE_ESM_INFORMATION_RESPONSE: m_s1ap_log->info("Uplink NAS: Received ESM Information Response\n"); m_s1ap_log->console("Uplink NAS: Received ESM Information Response\n"); - handle_esm_information_response(nas_msg, ue_ctx, reply_buffer, reply_flag); - ue_ctx->security_ctxt.ul_nas_count++; + handle_esm_information_response(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); break; case LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE: m_s1ap_log->info("Uplink NAS: Received Identity Response\n"); m_s1ap_log->console("Uplink NAS: Received Identity Response\n"); - handle_identity_response(nas_msg, ue_ctx, reply_buffer, reply_flag); - //ue_ctx->security_ctxt.ul_nas_count++; + handle_identity_response(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); break; case LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REQUEST: m_s1ap_log->info("UL NAS: Tracking Area Update Request\n"); - handle_tracking_area_update_request(nas_msg, ue_ctx, reply_buffer, reply_flag); + handle_tracking_area_update_request(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); 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 ); - return false; //FIXME (nas_msg deallocate needs to be called) + m_pool->deallocate(nas_msg); + return false; } if(*reply_flag == true) @@ -421,13 +417,19 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, } bool -s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag) +s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag) { LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_resp; bool ue_valid=true; - m_s1ap_log->console("Authentication Response -- IMSI %015lu\n", ue_ctx->imsi); + ue_emm_ctx_t *ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); + if(ue_emm_ctx == NULL) + { + m_s1ap_log->error("Authentication Response -- Could not find UE EMM context.\n"); + return false; + } + m_s1ap_log->console("Authentication Response -- IMSI %015lu\n", ue_emm_ctx->imsi); //Get NAS authentication response LIBLTE_ERROR_ENUM err = liblte_mme_unpack_authentication_response_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &auth_resp); @@ -444,7 +446,7 @@ s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *na for(int i=0; i<8;i++) { - if(auth_resp.res[i] != ue_ctx->security_ctxt.xres[i]) + if(auth_resp.res[i] != ue_emm_ctx->security_ctxt.xres[i]) { ue_valid = false; } @@ -455,14 +457,14 @@ s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *na std::cout<<"XRES: "; for(int i=0;i<8;i++) { - std::cout << std::hex <<(uint16_t)ue_ctx->security_ctxt.xres[i]; + std::cout << std::hex <<(uint16_t)ue_emm_ctx->security_ctxt.xres[i]; } std::cout<console("UE Authentication Rejected.\n"); m_s1ap_log->warning("UE Authentication Rejected.\n"); //Send back Athentication Reject - pack_authentication_reject(reply_buffer, ue_ctx->enb_ue_s1ap_id, ue_ctx->mme_ue_s1ap_id); + pack_authentication_reject(reply_buffer, ue_ecm_ctx->enb_ue_s1ap_id, ue_ecm_ctx->mme_ue_s1ap_id); *reply_flag = true; m_s1ap_log->console("Downlink NAS: Sending Authentication Reject.\n"); return false; @@ -472,7 +474,7 @@ s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *na m_s1ap_log->console("UE Authentication Accepted.\n"); m_s1ap_log->info("UE Authentication Accepted.\n"); //Send Security Mode Command - pack_security_mode_command(reply_buffer, ue_ctx); + pack_security_mode_command(reply_buffer, ue_emm_ctx, ue_ecm_ctx); *reply_flag = true; m_s1ap_log->console("Downlink NAS: Sending NAS Security Mode Command.\n"); } @@ -480,8 +482,16 @@ s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *na } bool -s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag) +s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag) { + + ue_emm_ctx_t *ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); + if(ue_emm_ctx == NULL) + { + m_s1ap_log->error("Could not find UE's EMM context\n"); + return false; + } + LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sm_comp; //Get NAS authentication response @@ -499,11 +509,11 @@ s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas m_s1ap_log->warning("IMEI-SV present but not handled"); } - m_s1ap_log->info("Security Mode Command Complete -- IMSI: %lu\n", ue_ctx->imsi); - m_s1ap_log->console("Security Mode Command Complete -- IMSI: %lu\n", ue_ctx->imsi); - if(ue_ctx->eit == true) + m_s1ap_log->info("Security Mode Command Complete -- IMSI: %lu\n", ue_ecm_ctx->imsi); + m_s1ap_log->console("Security Mode Command Complete -- IMSI: %lu\n", ue_ecm_ctx->imsi); + if(ue_ecm_ctx->eit == true) { - pack_esm_information_request(reply_buffer, ue_ctx); + pack_esm_information_request(reply_buffer, ue_emm_ctx, ue_ecm_ctx); m_s1ap_log->console("Sending ESM information request\n"); *reply_flag = true; } @@ -511,7 +521,7 @@ s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas { //FIXME The packging of GTP-C messages is not ready. //This means that GTP-U tunnels are created with function calls, as opposed to GTP-C. - m_mme_gtpc->send_create_session_request(ue_ctx->imsi, ue_ctx->mme_ue_s1ap_id); + m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi, ue_ecm_ctx->mme_ue_s1ap_id); *reply_flag = false; //No reply needed } return true; @@ -830,7 +840,7 @@ s1ap_nas_transport::unpack_authentication_response(LIBLTE_S1AP_MESSAGE_UPLINKNAS } bool -s1ap_nas_transport::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, ue_ctx_t *ue_ctx) +s1ap_nas_transport::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *ue_ecm_ctx) { srslte::byte_buffer_t *nas_buffer = m_pool->allocate(); @@ -888,7 +898,6 @@ s1ap_nas_transport::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, //Generate MAC for integrity protection //FIXME Write wrapper to support EIA1, EIA2, etc. - //TODO which is the RB ID? Standard says a constant, but which? uint8_t mac[4]; srslte::security_generate_k_nas( ue_ctx->security_ctxt.k_asme, @@ -925,7 +934,7 @@ s1ap_nas_transport::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, } bool -s1ap_nas_transport::pack_esm_information_request(srslte::byte_buffer_t *reply_msg, ue_ctx_t *ue_ctx) +s1ap_nas_transport::pack_esm_information_request(srslte::byte_buffer_t *reply_msg, ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *ue_ecm_ctx) { srslte::byte_buffer_t *nas_buffer = m_pool->allocate(); @@ -943,14 +952,14 @@ s1ap_nas_transport::pack_esm_information_request(srslte::byte_buffer_t *reply_ms //Setup Dw NAS structure LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT *dw_nas = &init->choice.DownlinkNASTransport; dw_nas->ext=false; - dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ctx->mme_ue_s1ap_id;//FIXME Change name - dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ctx->enb_ue_s1ap_id; + dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ecm_ctx->mme_ue_s1ap_id;//FIXME Change name + dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ecm_ctx->enb_ue_s1ap_id; dw_nas->HandoverRestrictionList_present=false; dw_nas->SubscriberProfileIDforRFP_present=false; LIBLTE_MME_ESM_INFORMATION_REQUEST_MSG_STRUCT esm_info_req; esm_info_req.eps_bearer_id=0; - esm_info_req.proc_transaction_id = ue_ctx->procedure_transaction_id; + esm_info_req.proc_transaction_id = ue_emm_ctx->procedure_transaction_id; uint8_t sec_hdr_type=2; ue_ctx->security_ctxt.dl_nas_count++; @@ -964,8 +973,8 @@ s1ap_nas_transport::pack_esm_information_request(srslte::byte_buffer_t *reply_ms } uint8_t mac[4]; - srslte::security_128_eia1 (&ue_ctx->security_ctxt.k_nas_int[16], - ue_ctx->security_ctxt.dl_nas_count, + srslte::security_128_eia1 (&ue_emm_ctx->security_ctxt.k_nas_int[16], + ue_emm_ctx->security_ctxt.dl_nas_count, 0, SECURITY_DIRECTION_DOWNLINK, &nas_buffer->msg[5], @@ -1210,24 +1219,30 @@ s1ap_nas_transport::pack_emm_information(srslte::byte_buffer_t *reply_msg, uint3 emm_info.net_dst_present = false; //Integrity check - ue_ctx_t * ue_ctx = m_s1ap->find_ue_ctx(mme_ue_s1ap_id); - if(ue_ctx == NULL) + ue_ecm_ctx_t * ue_ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); + if(ue_ecm_ctx == NULL) + { + return false; + } + ue_emm_ctx_t * ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); + if(ue_emm_ctx == NULL) { return false; } + uint8_t sec_hdr_type =2; - ue_ctx->security_ctxt.dl_nas_count++; - LIBLTE_ERROR_ENUM err = liblte_mme_pack_emm_information_msg(&emm_info, sec_hdr_type, ue_ctx->security_ctxt.dl_nas_count, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); + ue_emm_ctx->security_ctxt.dl_nas_count++; + LIBLTE_ERROR_ENUM err = liblte_mme_pack_emm_information_msg(&emm_info, sec_hdr_type, ue_emm_ctx->security_ctxt.dl_nas_count, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); if(err != LIBLTE_SUCCESS) { - m_s1ap_log->error("Error packing Identity Request\n"); - m_s1ap_log->console("Error packing Identity REquest\n"); + m_s1ap_log->error("Error packing EMM Information\n"); + m_s1ap_log->console("Error packing EMM Information\n"); return false; } uint8_t mac[4]; - srslte::security_128_eia1 (&ue_ctx->security_ctxt.k_nas_int[16], - ue_ctx->security_ctxt.dl_nas_count, + srslte::security_128_eia1 (&ue_emm_ctx->security_ctxt.k_nas_int[16], + ue_emm_ctx->security_ctxt.dl_nas_count, 0, SECURITY_DIRECTION_DOWNLINK, &nas_buffer->msg[5], From 97f60ae6ff71ceafbb576298de9b9aef942079df Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 6 Feb 2018 12:19:18 +0000 Subject: [PATCH 023/342] starting to change handle_attach_request to support separate EMM and ECM context. --- srsepc/hdr/mme/s1ap_common.h | 3 +- srsepc/src/mme/s1ap_nas_transport.cc | 149 ++++++++++++--------------- 2 files changed, 66 insertions(+), 86 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index bf07a7c70..7e12f8ed4 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -130,9 +130,10 @@ typedef struct{ typedef struct{ uint64_t imsi; LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT guti; - emm_state_t emm_state; eps_security_ctx_t security_ctxt; uint8_t procedure_transaction_id; + emm_state_t emm_state; + uint32_t mme_ue_s1ap_id; } ue_emm_ctx_t; typedef struct{ diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index ae84b328b..3e0817dbc 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -240,42 +240,49 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, uint8_t rand[16]; uint8_t xres[8]; - ue_ctx_t ue_ctx; - ue_ctx.imsi = 0; - ue_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; - ue_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + + ue_emm_ctx_t ue_emm_ctx; + ue_ecm_ctx_t ue_ecm_ctx; + + //Set UE's EMM context + ue_emm_ctx.imsi = 0; + for(int i=0;i<=14;i++){ + ue_emm_ctx.imsi += attach_req.eps_mobile_id.imsi[i]*std::pow(10,14-i); + } + ue_emm_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); //Save UE network capabilities - memcpy(&ue_ctx.security_ctxt.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT)); - ue_ctx.security_ctxt.ms_network_cap_present = attach_req.ms_network_cap_present; + memcpy(&ue_emm_ctx.security_ctxt.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT)); + ue_emm_ctx.security_ctxt.ms_network_cap_present = attach_req.ms_network_cap_present; if(attach_req.ms_network_cap_present) { - memcpy(&ue_ctx.security_ctxt.ms_network_cap, &attach_req.ms_network_cap, sizeof(LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT)); + memcpy(&ue_emm_ctx.security_ctxt.ms_network_cap, &attach_req.ms_network_cap, sizeof(LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT)); } uint8_t eps_bearer_id = pdn_con_req.eps_bearer_id; //TODO: Unused - ue_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id; + ue_emm_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id; - //Save whether ESM information transfer is necessary - ue_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; - //m_s1ap_log->console("EPS Bearer id: %d\n", eps_bearer_id); //Initialize NAS count - ue_ctx.security_ctxt.ul_nas_count = 0; - ue_ctx.security_ctxt.dl_nas_count = 0; + ue_emm_ctx.security_ctxt.ul_nas_count = 0; + ue_emm_ctx.security_ctxt.dl_nas_count = 0; + + + //Set UE ECM context + //Set eNB information + ue_ecm_ctx.enb_id = enb_ue_s1ap_id; + memcpy(&ue_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + + //Save whether ESM information transfer is necessary + ue_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; + //Add eNB info to UE ctxt - memcpy(&ue_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); //Initialize E-RABs for(uint i = 0 ; i< MAX_ERABS_PER_UE; i++) { - ue_ctx.erabs_ctx[i].state = ERAB_DEACTIVATED; - ue_ctx.erabs_ctx[i].erab_id = i; - } - - //IMSI style attach - ue_ctx.imsi = 0; - for(int i=0;i<=14;i++){ - ue_ctx.imsi += attach_req.eps_mobile_id.imsi[i]*std::pow(10,14-i); + ue_ecm_ctx.erabs_ctx[i].state = ERAB_DEACTIVATED; + ue_ecm_ctx.erabs_ctx[i].erab_id = i; } + //Log Attach Request information m_s1ap_log->console("Attach request -- IMSI: %015lu\n", ue_ctx.imsi); m_s1ap_log->info("Attach request -- IMSI: %015lu\n", ue_ctx.imsi); m_s1ap_log->console("Attach request -- eNB-UE S1AP Id: %d, MME-UE S1AP Id: %d\n", ue_ctx.enb_ue_s1ap_id, ue_ctx.mme_ue_s1ap_id); @@ -528,7 +535,7 @@ s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas } bool -s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) +s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) { LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_comp; @@ -559,12 +566,12 @@ s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, u m_s1ap_log->error("EPS Bearer ID out of range\n"); return false; } - m_mme_gtpc->send_modify_bearer_request(&ue_ctx->erabs_ctx[act_bearer.eps_bearer_id]); + m_mme_gtpc->send_modify_bearer_request(&ue_ecm_ctx->erabs_ctx[act_bearer.eps_bearer_id]); return true; } bool -s1ap_nas_transport::handle_esm_information_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) +s1ap_nas_transport::handle_esm_information_response(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) { LIBLTE_MME_ESM_INFORMATION_RESPONSE_MSG_STRUCT esm_info_resp; @@ -583,12 +590,12 @@ s1ap_nas_transport::handle_esm_information_response(srslte::byte_buffer_t *nas_m //FIXME The packging of GTP-C messages is not ready. //This means that GTP-U tunnels are created with function calls, as opposed to GTP-C. - m_mme_gtpc->send_create_session_request(ue_ctx->imsi, ue_ctx->mme_ue_s1ap_id); + m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi, ue_ecm_ctx->mme_ue_s1ap_id); return true; } bool -s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) +s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) { uint8_t autn[16]; uint8_t rand[16]; @@ -607,10 +614,13 @@ s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ } m_s1ap_log->info("Id Response -- IMSI: %015lu\n", imsi); m_s1ap_log->console("Id Response -- IMSI: %015lu\n", imsi); - ue_ctx->imsi = imsi; + ue_ecm_ctx->imsi = imsi; + + //Get UE EMM context + ue_emm_ctx_t ue_emm_ctx; //Get Authentication Vectors from HSS - if(!m_hss->gen_auth_info_answer(imsi, ue_ctx->security_ctxt.k_asme, autn, rand, ue_ctx->security_ctxt.xres)) + if(!m_hss->gen_auth_info_answer(imsi, ue_emm_ctx.security_ctxt.k_asme, autn, rand, ue_emm_ctx.security_ctxt.xres)) { m_s1ap_log->console("User not found. IMSI %015lu\n",imsi); m_s1ap_log->info("User not found. IMSI %015lu\n",imsi); @@ -618,7 +628,7 @@ s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ } //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); + pack_authentication_request(reply_msg, ue_ecm_ctx->enb_ue_s1ap_id, ue_ecm_ctx->mme_ue_s1ap_id, autn, rand); //Send reply to eNB *reply_flag = true; @@ -631,7 +641,7 @@ s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ bool -s1ap_nas_transport::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) +s1ap_nas_transport::handle_tracking_area_update_request(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) { /* @@ -657,45 +667,14 @@ s1ap_nas_transport::handle_tracking_area_update_request(srslte::byte_buffer_t *n //Setup Dw NAS structure LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT *dw_nas = &init->choice.DownlinkNASTransport; dw_nas->ext=false; - dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ctx->mme_ue_s1ap_id; - dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ctx->enb_ue_s1ap_id; + dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ecm_ctx->mme_ue_s1ap_id; + dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ecm_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_ecm_ctx->mme_ue_s1ap_id); LIBLTE_MME_TRACKING_AREA_UPDATE_ACCEPT_MSG_STRUCT tau_acc; - /*typedef struct{ - LIBLTE_MME_GPRS_TIMER_STRUCT t3412; - LIBLTE_MME_EPS_MOBILE_ID_STRUCT guti; - LIBLTE_MME_TRACKING_AREA_IDENTITY_LIST_STRUCT tai_list; - LIBLTE_MME_EPS_BEARER_CONTEXT_STATUS_STRUCT eps_bearer_context_status; - LIBLTE_MME_LOCATION_AREA_ID_STRUCT lai; - LIBLTE_MME_MOBILE_ID_STRUCT ms_id; - LIBLTE_MME_GPRS_TIMER_STRUCT t3402; - LIBLTE_MME_GPRS_TIMER_STRUCT t3423; - LIBLTE_MME_PLMN_LIST_STRUCT equivalent_plmns; - LIBLTE_MME_EMERGENCY_NUMBER_LIST_STRUCT emerg_num_list; - LIBLTE_MME_EPS_NETWORK_FEATURE_SUPPORT_STRUCT eps_network_feature_support; - LIBLTE_MME_GPRS_TIMER_3_STRUCT t3412_ext; - LIBLTE_MME_ADDITIONAL_UPDATE_RESULT_ENUM additional_update_result; - uint8 eps_update_result; - uint8 emm_cause; - bool t3412_present; - bool guti_present; - bool tai_list_present; - bool eps_bearer_context_status_present; - bool lai_present; - bool ms_id_present; - bool emm_cause_present; - bool t3402_present; - bool t3423_present; - bool equivalent_plmns_present; - bool emerg_num_list_present; - bool eps_network_feature_support_present; - bool additional_update_result_present; - bool t3412_ext_present; -}LIBLTE_MME_TRACKING_AREA_UPDATE_ACCEPT_MSG_STRUCT; -*/ + //Send reply to eNB //*reply_flag = true; @@ -858,8 +837,8 @@ s1ap_nas_transport::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, //Setup Dw NAS structure LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT *dw_nas = &init->choice.DownlinkNASTransport; dw_nas->ext=false; - dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ctx->mme_ue_s1ap_id; - dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ctx->enb_ue_s1ap_id; + dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ecm_ctx->mme_ue_s1ap_id; + dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ecm_ctx->enb_ue_s1ap_id; dw_nas->HandoverRestrictionList_present=false; dw_nas->SubscriberProfileIDforRFP_present=false; @@ -873,14 +852,14 @@ s1ap_nas_transport::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, sm_cmd.nas_ksi.nas_ksi=0; //Replay UE security cap - memcpy(sm_cmd.ue_security_cap.eea,ue_ctx->security_ctxt.ue_network_cap.eea,8*sizeof(bool)); - memcpy(sm_cmd.ue_security_cap.eia,ue_ctx->security_ctxt.ue_network_cap.eia,8*sizeof(bool)); - sm_cmd.ue_security_cap.uea_present = ue_ctx->security_ctxt.ue_network_cap.uea_present; - memcpy(sm_cmd.ue_security_cap.uea,ue_ctx->security_ctxt.ue_network_cap.uea,8*sizeof(bool)); - sm_cmd.ue_security_cap.uia_present = ue_ctx->security_ctxt.ue_network_cap.uia_present; - memcpy(sm_cmd.ue_security_cap.uia,ue_ctx->security_ctxt.ue_network_cap.uia,8*sizeof(bool)); - sm_cmd.ue_security_cap.gea_present = ue_ctx->security_ctxt.ms_network_cap_present; - memcpy(sm_cmd.ue_security_cap.gea,ue_ctx->security_ctxt.ms_network_cap.gea,8*sizeof(bool)); + memcpy(sm_cmd.ue_security_cap.eea,ue_emm_ctx->security_ctxt.ue_network_cap.eea,8*sizeof(bool)); + memcpy(sm_cmd.ue_security_cap.eia,ue_emm_ctx->security_ctxt.ue_network_cap.eia,8*sizeof(bool)); + sm_cmd.ue_security_cap.uea_present = ue_emm_ctx->security_ctxt.ue_network_cap.uea_present; + memcpy(sm_cmd.ue_security_cap.uea,ue_emm_ctx->security_ctxt.ue_network_cap.uea,8*sizeof(bool)); + sm_cmd.ue_security_cap.uia_present = ue_emm_ctx->security_ctxt.ue_network_cap.uia_present; + memcpy(sm_cmd.ue_security_cap.uia,ue_emm_ctx->security_ctxt.ue_network_cap.uia,8*sizeof(bool)); + sm_cmd.ue_security_cap.gea_present = ue_emm_ctx->security_ctxt.ms_network_cap_present; + memcpy(sm_cmd.ue_security_cap.gea,ue_emm_ctx->security_ctxt.ms_network_cap.gea,8*sizeof(bool)); sm_cmd.imeisv_req_present=false; sm_cmd.nonce_ue_present=false; @@ -888,8 +867,8 @@ s1ap_nas_transport::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, uint8_t sec_hdr_type=3; - ue_ctx->security_ctxt.dl_nas_count = 0; - LIBLTE_ERROR_ENUM err = liblte_mme_pack_security_mode_command_msg(&sm_cmd,sec_hdr_type, ue_ctx->security_ctxt.dl_nas_count,(LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); + ue_emm_ctx->security_ctxt.dl_nas_count = 0; + LIBLTE_ERROR_ENUM err = liblte_mme_pack_security_mode_command_msg(&sm_cmd,sec_hdr_type, ue_emm_ctx->security_ctxt.dl_nas_count,(LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); if(err != LIBLTE_SUCCESS) { m_s1ap_log->console("Error packing Athentication Request\n"); @@ -900,15 +879,15 @@ s1ap_nas_transport::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, //FIXME Write wrapper to support EIA1, EIA2, etc. uint8_t mac[4]; - srslte::security_generate_k_nas( ue_ctx->security_ctxt.k_asme, + srslte::security_generate_k_nas( ue_emm_ctx->security_ctxt.k_asme, srslte::CIPHERING_ALGORITHM_ID_EEA0, srslte::INTEGRITY_ALGORITHM_ID_128_EIA1, - ue_ctx->security_ctxt.k_nas_enc, - ue_ctx->security_ctxt.k_nas_int + ue_emm_ctx->security_ctxt.k_nas_enc, + ue_emm_ctx->security_ctxt.k_nas_int ); - srslte::security_128_eia1 (&ue_ctx->security_ctxt.k_nas_int[16], - ue_ctx->security_ctxt.dl_nas_count, + srslte::security_128_eia1 (&ue_emm_ctx->security_ctxt.k_nas_int[16], + ue_emm_ctx->security_ctxt.dl_nas_count, 0, SECURITY_DIRECTION_DOWNLINK, &nas_buffer->msg[5], @@ -962,9 +941,9 @@ s1ap_nas_transport::pack_esm_information_request(srslte::byte_buffer_t *reply_ms esm_info_req.proc_transaction_id = ue_emm_ctx->procedure_transaction_id; uint8_t sec_hdr_type=2; - ue_ctx->security_ctxt.dl_nas_count++; + ue_emm_ctx->security_ctxt.dl_nas_count++; - LIBLTE_ERROR_ENUM err = srslte_mme_pack_esm_information_request_msg(&esm_info_req, sec_hdr_type,ue_ctx->security_ctxt.dl_nas_count,(LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); + LIBLTE_ERROR_ENUM err = srslte_mme_pack_esm_information_request_msg(&esm_info_req, sec_hdr_type,ue_emm_ctx->security_ctxt.dl_nas_count,(LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); if(err != LIBLTE_SUCCESS) { m_s1ap_log->error("Error packing ESM information request\n"); From 7306d00ea52cb5429998575b61696332a93d2a56 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 6 Feb 2018 12:58:47 +0000 Subject: [PATCH 024/342] Changed attach request handling for separate EMM and ECM context. --- srsepc/src/mme/s1ap_nas_transport.cc | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 3e0817dbc..98d89e507 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -267,11 +267,13 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, //Set UE ECM context + ue_ecm_ctx.imsi = ue_emm_ctx.imsi; + ue_ecm_ctx.mme_ue_s1ap_id = ue_emm_ctx.mme_ue_s1ap_id; //Set eNB information ue_ecm_ctx.enb_id = enb_ue_s1ap_id; memcpy(&ue_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); - //Save whether ESM information transfer is necessary + //Save whether secure ESM information transfer is necessary ue_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; //Add eNB info to UE ctxt @@ -283,9 +285,9 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, } //Log Attach Request information - m_s1ap_log->console("Attach request -- IMSI: %015lu\n", ue_ctx.imsi); - m_s1ap_log->info("Attach request -- IMSI: %015lu\n", ue_ctx.imsi); - m_s1ap_log->console("Attach request -- eNB-UE S1AP Id: %d, MME-UE S1AP Id: %d\n", ue_ctx.enb_ue_s1ap_id, ue_ctx.mme_ue_s1ap_id); + m_s1ap_log->console("Attach request -- IMSI: %015lu\n", ue_emm_ctx.imsi); + m_s1ap_log->info("Attach request -- IMSI: %015lu\n", ue_emm_ctx.imsi); + m_s1ap_log->console("Attach request -- eNB-UE S1AP Id: %d, MME-UE S1AP Id: %d\n", ue_ecm_ctx.enb_ue_s1ap_id, ue_ecm_ctx.mme_ue_s1ap_id); m_s1ap_log->console("Attach Request -- UE Network Capabilities EEA: %d%d%d%d%d%d%d%d\n", attach_req.ue_network_cap.eea[0], attach_req.ue_network_cap.eea[1], @@ -310,16 +312,18 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, m_s1ap_log->console("PDN Connectivity Request -- ESM Information Transfer requested: %s\n", pdn_con_req.esm_info_transfer_flag_present ? "true" : "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)) + if(!m_hss->gen_auth_info_answer(ue_emm_ctx.imsi, ue_emm_ctx.security_ctxt.k_asme, autn, rand, ue_emm_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); + m_s1ap_log->console("User not found. IMSI %015lu\n",ue_emm_ctx.imsi); + m_s1ap_log->info("User not found. IMSI %015lu\n",ue_emm_ctx.imsi); return false; } - m_s1ap->add_new_ue_ctx(ue_ctx); + m_s1ap->add_new_ue_emm_ctx(ue_emm_ctx); + m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); + //Pack NAS Authentication Request in Downlink NAS Transport msg - pack_authentication_request(reply_buffer, ue_ctx.enb_ue_s1ap_id, ue_ctx.mme_ue_s1ap_id, autn, rand); + pack_authentication_request(reply_buffer, ue_ecm_ctx.enb_ue_s1ap_id, ue_ecm_ctx.mme_ue_s1ap_id, autn, rand); //Send reply to eNB *reply_flag = true; From 7c21b4cc111db7a9dd4947daee5255b60dbcb27c Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 6 Feb 2018 14:37:39 +0000 Subject: [PATCH 025/342] changing handle of guti attach request. --- srsepc/src/mme/s1ap_nas_transport.cc | 51 ++++++++++++++++------------ 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 98d89e507..6095535fc 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -346,38 +346,44 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, if(it == m_s1ap->m_tmsi_to_s1ap_id.end()) { //Could not find IMSI from M-TMSI, send Id request - ue_ctx_t ue_ctx; - ue_ctx.imsi = 0; - ue_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; - ue_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + ue_emm_ctx_t tmp_ue_emm_ctx; + ue_ecm_ctx_t ue_ecm_ctx; + + //Set tmp UE EMM context + tmp_ue_emm_ctx.imsi = 0; //Save UE network capabilities - memcpy(&ue_ctx.security_ctxt.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT)); - ue_ctx.security_ctxt.ms_network_cap_present = attach_req.ms_network_cap_present; + memcpy(&tmp_ue_emm_ctx.security_ctxt.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT)); + tmp_ue_emm_ctx.security_ctxt.ms_network_cap_present = attach_req.ms_network_cap_present; if(attach_req.ms_network_cap_present) { - memcpy(&ue_ctx.security_ctxt.ms_network_cap, &attach_req.ms_network_cap, sizeof(LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT)); + memcpy(&tmp_ue_emm_ctx.security_ctxt.ms_network_cap, &attach_req.ms_network_cap, sizeof(LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT)); } + //Initialize NAS count + tmp_ue_emm_ctx.security_ctxt.ul_nas_count = 0; + tmp_ue_emm_ctx.security_ctxt.dl_nas_count = 0; + tmp_ue_emm_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id; + + //Set ECM context + ue_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; + ue_ecm_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + uint8_t eps_bearer_id = pdn_con_req.eps_bearer_id; //TODO: Unused - ue_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id; //Save whether ESM information transfer is necessary - ue_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; + ue_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; //m_s1ap_log->console("EPS Bearer id: %d\n", eps_bearer_id); - //Initialize NAS count - ue_ctx.security_ctxt.ul_nas_count = 0; - ue_ctx.security_ctxt.dl_nas_count = 0; - //Add eNB info to UE ctxt - memcpy(&ue_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + //Add eNB info to UE ctxt + memcpy(&ue_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); //Initialize E-RABs for(uint i = 0 ; i< MAX_ERABS_PER_UE; i++) { - ue_ctx.erabs_ctx[i].state = ERAB_DEACTIVATED; - ue_ctx.erabs_ctx[i].erab_id = i; + ue_ecm_ctx.erabs_ctx[i].state = ERAB_DEACTIVATED; + ue_ecm_ctx.erabs_ctx[i].erab_id = i; } - m_s1ap_log->console("Attach request -- IMSI: %015lu\n", ue_ctx.imsi); - m_s1ap_log->info("Attach request -- IMSI: %015lu\n", ue_ctx.imsi); - m_s1ap_log->console("Attach request -- eNB-UE S1AP Id: %d, MME-UE S1AP Id: %d\n", ue_ctx.enb_ue_s1ap_id, ue_ctx.mme_ue_s1ap_id); + m_s1ap_log->console("Attach request -- IMSI: %015lu\n", ue_ecm_ctx.imsi); + m_s1ap_log->info("Attach request -- IMSI: %015lu\n", ue_ecm_ctx.imsi); + m_s1ap_log->console("Attach request -- eNB-UE S1AP Id: %d, MME-UE S1AP Id: %d\n", ue_ecm_ctx.enb_ue_s1ap_id, ue_ecm_ctx.mme_ue_s1ap_id); m_s1ap_log->console("Attach Request -- UE Network Capabilities EEA: %d%d%d%d%d%d%d%d\n", attach_req.ue_network_cap.eea[0], attach_req.ue_network_cap.eea[1], @@ -403,13 +409,15 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, m_s1ap_log->console("Could not find M-TMSI=0x%x. Sending ID request\n",m_tmsi); m_s1ap_log->info("Could not find M-TMSI=0x%d. Sending Id Request\n", m_tmsi); - m_s1ap->add_new_ue_ctx(ue_ctx); - pack_identity_request(reply_buffer, ue_ctx.enb_ue_s1ap_id, ue_ctx.mme_ue_s1ap_id); + m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); + pack_identity_request(reply_buffer, ue_ecm_ctx.enb_ue_s1ap_id, ue_ecm_ctx.mme_ue_s1ap_id); *reply_flag = true; return true; } else{ + m_s1ap_log->console("Attach Request -- Found M-TMSI: %d\n",m_tmsi); + /* ue_ctx_t *ue_ctx_ptr = m_s1ap->find_ue_ctx(it->second); if(ue_ctx_ptr!=NULL) { @@ -423,6 +431,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, m_s1ap_log->error("Found M-TMSI but could not find UE context\n"); return false; } + */ } return true; } From 86adc29ce8453fe037052f7c0e98d250e40cb757 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 6 Feb 2018 16:23:41 +0000 Subject: [PATCH 026/342] Changing send initial context setup. --- srsepc/hdr/mme/s1ap_nas_transport.h | 2 +- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 34 ++++++++++++++++----------- srsepc/src/mme/s1ap_nas_transport.cc | 14 +++++------ 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index 3e897c0a4..c38ae2bb3 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -79,7 +79,7 @@ public: bool pack_security_mode_command(srslte::byte_buffer_t *reply_msg, ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *ue_ecm_ctx); bool pack_esm_information_request(srslte::byte_buffer_t *reply_msg, ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *ue_ecm_ctx); - bool pack_attach_accept(ue_ctx_t *ue_ctx, LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *erab_ctxt, struct srslte::gtpc_pdn_address_allocation_ie *paa, srslte::byte_buffer_t *nas_buffer); + bool pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *ue_ecm_ctx, LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *erab_ctxt, struct srslte::gtpc_pdn_address_allocation_ie *paa, srslte::byte_buffer_t *nas_buffer); bool pack_identity_request(srslte::byte_buffer_t *reply_msg, uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id); bool pack_emm_information(srslte::byte_buffer_t *reply_msg, uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id); diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 1d6df8cf3..60d50e173 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -98,19 +98,25 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, m_s1ap_log->info("Preparing to send Initial Context Setup request\n"); //Find UE Context - ue_ctx_t *ue_ctx = m_s1ap->find_ue_ctx(mme_ue_s1ap_id); - if(ue_ctx == NULL) + ue_ecm_ctx_t *ue_ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); + if(ue_ecm_ctx == NULL) + { + m_s1ap_log->error("Could not find UE to send Setup Context Request. MME S1AP Id: %d", mme_ue_s1ap_id); + return false; + } + ue_emm_ctx_t *ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); + if(ue_emm_ctx == NULL) { m_s1ap_log->error("Could not find UE to send Setup Context Request. MME S1AP Id: %d", mme_ue_s1ap_id); return false; } //Add MME and eNB S1AP Ids - in_ctxt_req->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ctx->mme_ue_s1ap_id; - in_ctxt_req->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ctx->enb_ue_s1ap_id; + in_ctxt_req->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ecm_ctx->mme_ue_s1ap_id; + in_ctxt_req->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ecm_ctx->enb_ue_s1ap_id; //Set UE-AMBR - in_ctxt_req->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateDL.BitRate=1000000000;//2^32-1 + in_ctxt_req->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateDL.BitRate=1000000000; in_ctxt_req->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateUL.BitRate=1000000000;//FIXME Get UE-AMBR from HSS //Setup eRAB context @@ -143,7 +149,7 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, bzero(in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer,sizeof(uint8_t)*16); for(int i = 0; i<3; i++) { - if(ue_ctx->security_ctxt.ue_network_cap.eea[i+1] == true) + if(ue_emm_ctx->security_ctxt.ue_network_cap.eea[i+1] == true) { in_ctxt_req->UESecurityCapabilities.encryptionAlgorithms.buffer[i] = 1; //EEA supported } @@ -151,7 +157,7 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, { in_ctxt_req->UESecurityCapabilities.encryptionAlgorithms.buffer[i] = 0; //EEA not supported } - if(ue_ctx->security_ctxt.ue_network_cap.eia[i+1] == true) + if(ue_emm_ctx->security_ctxt.ue_network_cap.eia[i+1] == true) { in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer[i] = 1; //EEA supported } @@ -162,9 +168,9 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, // in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer[0] = 1; //EIA1 } uint8_t key_enb[32]; - liblte_security_generate_k_enb(ue_ctx->security_ctxt.k_asme, ue_ctx->security_ctxt.ul_nas_count, key_enb); + liblte_security_generate_k_enb(ue_emm_ctx->security_ctxt.k_asme, ue_emm_ctx->security_ctxt.ul_nas_count, key_enb); liblte_unpack(key_enb, 32, in_ctxt_req->SecurityKey.buffer); - m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",ue_ctx->security_ctxt.ul_nas_count); + m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",ue_emm_ctx->security_ctxt.ul_nas_count); //Set Attach accepted and activat default bearer NAS messages if(cs_resp->paa_present != true) { @@ -177,7 +183,7 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, return false; } srslte::byte_buffer_t *nas_buffer = m_pool->allocate(); - m_s1ap_nas_transport->pack_attach_accept(ue_ctx, erab_ctxt, &cs_resp->paa, nas_buffer); + m_s1ap_nas_transport->pack_attach_accept(ue_emm_ctx, ue_ecm_ctx, erab_ctxt, &cs_resp->paa, nas_buffer); LIBLTE_ERROR_ENUM err = liblte_s1ap_pack_s1ap_pdu(&pdu, (LIBLTE_BYTE_MSG_STRUCT*)reply_buffer); @@ -187,7 +193,7 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, return false; } //Send Reply to eNB - ssize_t n_sent = sctp_send(s1mme,reply_buffer->msg, reply_buffer->N_bytes, &ue_ctx->enb_sri, 0); + ssize_t n_sent = sctp_send(s1mme,reply_buffer->msg, reply_buffer->N_bytes, &ue_ecm_ctx->enb_sri, 0); if(n_sent == -1) { m_s1ap_log->error("Failed to send Initial Context Setup Request\n"); @@ -195,9 +201,9 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, } //Change E-RAB state to Context Setup Requested and save S-GW control F-TEID - ue_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].state = ERAB_CTX_REQUESTED; - ue_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.teid = sgw_ctrl_fteid.teid; - ue_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.ipv4 = sgw_ctrl_fteid.ipv4; + ue_ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].state = ERAB_CTX_REQUESTED; + ue_ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.teid = sgw_ctrl_fteid.teid; + ue_ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.ipv4 = sgw_ctrl_fteid.ipv4; struct in_addr addr; addr.s_addr = htonl(sgw_s1u_ip); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 6095535fc..6bbab6947 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -993,7 +993,7 @@ s1ap_nas_transport::pack_esm_information_request(srslte::byte_buffer_t *reply_ms } bool -s1ap_nas_transport::pack_attach_accept(ue_ctx_t *ue_ctx, LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *erab_ctxt, struct srslte::gtpc_pdn_address_allocation_ie *paa, srslte::byte_buffer_t *nas_buffer) { +s1ap_nas_transport::pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *ue_ecm_ctx, LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *erab_ctxt, struct srslte::gtpc_pdn_address_allocation_ie *paa, srslte::byte_buffer_t *nas_buffer) { LIBLTE_MME_ATTACH_ACCEPT_MSG_STRUCT attach_accept; LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT act_def_eps_bearer_context_req; //bzero(&act_def_eps_bearer_context_req,sizeof(LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT)); @@ -1040,7 +1040,7 @@ s1ap_nas_transport::pack_attach_accept(ue_ctx_t *ue_ctx, LIBLTE_S1AP_E_RABTOBESE attach_accept.guti.guti.mnc = mnc; attach_accept.guti.guti.mme_group_id = m_s1ap->m_s1ap_args.mme_group; attach_accept.guti.guti.mme_code = m_s1ap->m_s1ap_args.mme_code; - attach_accept.guti.guti.m_tmsi = m_s1ap->allocate_m_tmsi(ue_ctx->mme_ue_s1ap_id); + attach_accept.guti.guti.m_tmsi = m_s1ap->allocate_m_tmsi(ue_ecm_ctx->mme_ue_s1ap_id); m_s1ap_log->debug("Allocated GUTI: MCC %d, MNC %d, MME Group Id %d, MME Code 0x%x, M-TMSI 0x%x\n", attach_accept.guti.guti.mcc, attach_accept.guti.guti.mnc, @@ -1077,7 +1077,7 @@ s1ap_nas_transport::pack_attach_accept(ue_ctx_t *ue_ctx, LIBLTE_S1AP_E_RABTOBESE //act_def_eps_bearer_context_req.apn std::string apn("test123"); act_def_eps_bearer_context_req.apn.apn = apn; //FIXME - act_def_eps_bearer_context_req.proc_transaction_id = ue_ctx->procedure_transaction_id; //FIXME + act_def_eps_bearer_context_req.proc_transaction_id = ue_emm_ctx->procedure_transaction_id; //FIXME //Set DNS server act_def_eps_bearer_context_req.protocol_cnfg_opts_present = true; @@ -1098,13 +1098,13 @@ s1ap_nas_transport::pack_attach_accept(ue_ctx_t *ue_ctx, LIBLTE_S1AP_E_RABTOBESE act_def_eps_bearer_context_req.esm_cause_present = false; uint8_t sec_hdr_type =2; - ue_ctx->security_ctxt.dl_nas_count++; + ue_emm_ctx->security_ctxt.dl_nas_count++; liblte_mme_pack_activate_default_eps_bearer_context_request_msg(&act_def_eps_bearer_context_req, &attach_accept.esm_msg); - liblte_mme_pack_attach_accept_msg(&attach_accept, sec_hdr_type, ue_ctx->security_ctxt.dl_nas_count, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); + liblte_mme_pack_attach_accept_msg(&attach_accept, sec_hdr_type, ue_emm_ctx->security_ctxt.dl_nas_count, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); //Integrity protect NAS message uint8_t mac[4]; - srslte::security_128_eia1 (&ue_ctx->security_ctxt.k_nas_int[16], - ue_ctx->security_ctxt.dl_nas_count, + srslte::security_128_eia1 (&ue_emm_ctx->security_ctxt.k_nas_int[16], + ue_emm_ctx->security_ctxt.dl_nas_count, 0, SECURITY_DIRECTION_DOWNLINK, &nas_buffer->msg[5], From 0c013c19caf358b45051be25122829bdaf535642 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 6 Feb 2018 16:33:58 +0000 Subject: [PATCH 027/342] changed handle intial context setup response. --- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 60d50e173..4a31a0111 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -222,8 +222,8 @@ s1ap_ctx_mngmt_proc::handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_I { uint32_t mme_ue_s1ap_id = in_ctxt_resp->MME_UE_S1AP_ID.MME_UE_S1AP_ID; - ue_ctx_t *ue_ctx = m_s1ap->find_ue_ctx(mme_ue_s1ap_id); - if (ue_ctx == NULL) + ue_ecm_ctx_t *ue_ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); + if (ue_ecm_ctx == NULL) { m_s1ap_log->error("Could not find UE's context in active UE's map\n"); return false; @@ -233,7 +233,7 @@ s1ap_ctx_mngmt_proc::handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_I for(uint32_t i=0; iE_RABSetupListCtxtSURes.len;i++) { uint8_t erab_id = in_ctxt_resp->E_RABSetupListCtxtSURes.buffer[i].e_RAB_ID.E_RAB_ID; - erab_ctx_t *erab_ctx = &ue_ctx->erabs_ctx[erab_id]; + erab_ctx_t *erab_ctx = &ue_ecm_ctx->erabs_ctx[erab_id]; if (erab_ctx->state != ERAB_CTX_REQUESTED) { m_s1ap_log->error("E-RAB requested was not active %d\n",erab_id); From af927eb1d8d45ca5a4127e14c0439ee0ae1ce13e Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 6 Feb 2018 17:21:18 +0000 Subject: [PATCH 028/342] Changing handling of ue context release request. Compiling now, needs testing. --- srsepc/hdr/mme/mme_gtpc.h | 2 +- srsepc/src/mme/mme_gtpc.cc | 6 +++--- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 12 +++++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index f2804e22b..402a52a99 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -52,7 +52,7 @@ public: void handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu); void send_modify_bearer_request(erab_ctx_t *bearer_ctx); void handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu); - void send_delete_session_request(ue_ctx_t *ue_ctx); + void send_delete_session_request(ue_ecm_ctx_t *ue_ecm_ctx); private: diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 4b396f7a8..6f4a1cdcc 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -219,7 +219,7 @@ mme_gtpc::handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu) } void -mme_gtpc::send_delete_session_request(ue_ctx_t *ue_ctx) +mme_gtpc::send_delete_session_request(ue_ecm_ctx_t *ue_ecm_ctx) { m_mme_gtpc_log->info("Sending GTP-C Delete Session Request request\n"); srslte::gtpc_pdu del_req_pdu; @@ -230,9 +230,9 @@ mme_gtpc::send_delete_session_request(ue_ctx_t *ue_ctx) for(int i = 0; ierabs_ctx[i].state != ERAB_DEACTIVATED) + if(ue_ecm_ctx->erabs_ctx[i].state != ERAB_DEACTIVATED) { - sgw_ctrl_fteid = &ue_ctx->erabs_ctx[i].sgw_ctrl_fteid; + sgw_ctrl_fteid = &ue_ecm_ctx->erabs_ctx[i].sgw_ctrl_fteid; break; } } diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 4a31a0111..3fce06de6 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -272,8 +272,8 @@ s1ap_ctx_mngmt_proc::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECON m_s1ap_log->info("Received UE Context Release Request. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); m_s1ap_log->console("Received UE Context Release Request. MME-UE S1AP Id %d\n", mme_ue_s1ap_id); - ue_ctx_t *ue_ctx = m_s1ap->find_ue_ctx(mme_ue_s1ap_id); - if(ue_ctx == NULL) + ue_ecm_ctx_t *ue_ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); + if(ue_ecm_ctx == NULL) { m_s1ap_log->info("UE not found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); return false; @@ -283,7 +283,7 @@ s1ap_ctx_mngmt_proc::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECON bool active = false; for(int i=0;ierabs_ctx[i].state != ERAB_DEACTIVATED) + if(ue_ecm_ctx->erabs_ctx[i].state != ERAB_DEACTIVATED) //FIXME use ECM state { active = true; //ue_ctx->erabs_ctx[i].state = ERAB_DEACTIVATED; @@ -293,14 +293,16 @@ s1ap_ctx_mngmt_proc::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECON if(active == true) { //There are active E-RABs, send delete session request - m_mme_gtpc->send_delete_session_request(ue_ctx); + m_mme_gtpc->send_delete_session_request(ue_ecm_ctx); } //m_s1ap->delete_ue_ctx(ue_ctx); for(int i=0;ierabs_ctx[i].state = ERAB_DEACTIVATED; + ue_ecm_ctx->erabs_ctx[i].state = ERAB_DEACTIVATED; } //Delete UE context + m_s1ap->delete_ue_ecm_ctx(ue_ecm_ctx->mme_ue_s1ap_id); + m_s1ap_log->info("Deleted UE Context.\n"); return true; } From 47b574a3bad5367438fda844b1c747a85bec4e3e Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 6 Feb 2018 18:59:53 +0000 Subject: [PATCH 029/342] Removed unused value in ECM ctx --- srsepc/hdr/mme/s1ap_common.h | 1 - srsepc/src/mme/s1ap_nas_transport.cc | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index 7e12f8ed4..84ced0637 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -140,7 +140,6 @@ typedef struct{ uint64_t imsi; uint32_t enb_ue_s1ap_id; uint32_t mme_ue_s1ap_id; - uint16_t enb_id; struct sctp_sndrcvinfo enb_sri; ecm_state_t ecm_state; bool eit; diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 6bbab6947..76719efbe 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -270,7 +270,7 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, ue_ecm_ctx.imsi = ue_emm_ctx.imsi; ue_ecm_ctx.mme_ue_s1ap_id = ue_emm_ctx.mme_ue_s1ap_id; //Set eNB information - ue_ecm_ctx.enb_id = enb_ue_s1ap_id; + ue_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; memcpy(&ue_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); //Save whether secure ESM information transfer is necessary From 95bc4f8b08eee99cdebbc6fd2af5e0c8a5f4b1af Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 7 Feb 2018 14:11:42 +0000 Subject: [PATCH 030/342] adding tmp emm storage for when the UE uses an unknown guti and id request has to be sent. --- srsepc/hdr/mme/s1ap.h | 4 ++++ srsepc/src/mme/s1ap.cc | 25 +++++++++++++++++++++++++ srsepc/src/mme/s1ap_nas_transport.cc | 27 ++++++++++----------------- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 9e23868e8..bb0140c57 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -91,6 +91,9 @@ public: bool delete_ue_ecm_ctx(uint32_t mme_ue_s1ap_id); void delete_ues_ecm_ctx_in_enb(uint16_t enb_id); + void store_tmp_ue_emm_ctx(const ue_emm_ctx_t &ue_ecm_ctx); + bool get_tmp_ue_emm_ctx(uint32_t mme_ue_s1ap_id, ue_emm_ctx_t* ue_emm_ptr); + uint32_t allocate_m_tmsi(uint32_t mme_ue_s1ap_id); s1ap_args_t m_s1ap_args; @@ -119,6 +122,7 @@ private: std::map m_imsi_to_ue_emm_ctx; std::map m_mme_ue_s1ap_id_to_ue_ecm_ctx; + std::map m_mme_ue_s1ap_id_to_tmp_ue_emm_ctx; uint32_t m_next_mme_ue_s1ap_id; uint32_t m_next_m_tmsi; diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index d421191d5..9a9ebafee 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -346,6 +346,31 @@ s1ap::add_new_ue_emm_ctx(const ue_emm_ctx_t &ue_emm_ctx) m_imsi_to_ue_emm_ctx.insert(std::pair(ue_ptr->imsi,ue_ptr)); } +void +s1ap::store_tmp_ue_emm_ctx(const ue_emm_ctx_t &tmp_ue_emm_ctx) +{ + ue_emm_ctx_t *ue_ptr = new ue_emm_ctx_t; + memcpy(ue_ptr,&tmp_ue_emm_ctx,sizeof(tmp_ue_emm_ctx)); + + //This map will store UE's ECM context. + m_mme_ue_s1ap_id_to_tmp_ue_emm_ctx.insert(std::pair(ue_ptr->mme_ue_s1ap_id,ue_ptr)); +} + +bool +s1ap::get_tmp_ue_emm_ctx(uint32_t mme_ue_s1ap_id, ue_emm_ctx_t* ue_emm_ptr) +{ + + std::map::iterator it = m_mme_ue_s1ap_id_to_tmp_ue_emm_ctx.find(mme_ue_s1ap_id); + if(it == m_mme_ue_s1ap_id_to_tmp_ue_emm_ctx.end() ) + { + return false; + } + memcpy(ue_emm_ptr, it->second,sizeof(ue_emm_ctx_t)); + delete it->second; + m_mme_ue_s1ap_id_to_tmp_ue_emm_ctx.erase(it); + return true; +} + void s1ap::add_new_ue_ecm_ctx(const ue_ecm_ctx_t &ue_ecm_ctx) { diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 76719efbe..4998f68e4 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -385,31 +385,24 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, m_s1ap_log->info("Attach request -- IMSI: %015lu\n", ue_ecm_ctx.imsi); m_s1ap_log->console("Attach request -- eNB-UE S1AP Id: %d, MME-UE S1AP Id: %d\n", ue_ecm_ctx.enb_ue_s1ap_id, ue_ecm_ctx.mme_ue_s1ap_id); m_s1ap_log->console("Attach Request -- UE Network Capabilities EEA: %d%d%d%d%d%d%d%d\n", - attach_req.ue_network_cap.eea[0], - attach_req.ue_network_cap.eea[1], - attach_req.ue_network_cap.eea[2], - attach_req.ue_network_cap.eea[3], - attach_req.ue_network_cap.eea[4], - attach_req.ue_network_cap.eea[5], - attach_req.ue_network_cap.eea[6], - attach_req.ue_network_cap.eea[7]); + attach_req.ue_network_cap.eea[0], attach_req.ue_network_cap.eea[1], attach_req.ue_network_cap.eea[2], attach_req.ue_network_cap.eea[3], + attach_req.ue_network_cap.eea[4], attach_req.ue_network_cap.eea[5], attach_req.ue_network_cap.eea[6], attach_req.ue_network_cap.eea[7]); m_s1ap_log->console("Attach Request -- UE Network Capabilities EIA: %d%d%d%d%d%d%d%d\n", - attach_req.ue_network_cap.eia[0], - attach_req.ue_network_cap.eia[1], - attach_req.ue_network_cap.eia[2], - attach_req.ue_network_cap.eia[3], - attach_req.ue_network_cap.eia[4], - attach_req.ue_network_cap.eia[5], - attach_req.ue_network_cap.eia[6], - attach_req.ue_network_cap.eia[7]); + attach_req.ue_network_cap.eia[0], attach_req.ue_network_cap.eia[1], attach_req.ue_network_cap.eia[2], attach_req.ue_network_cap.eia[3], + attach_req.ue_network_cap.eia[4], attach_req.ue_network_cap.eia[5], attach_req.ue_network_cap.eia[6], attach_req.ue_network_cap.eia[7]); m_s1ap_log->console("Attach Request -- MS Network Capabilities Present: %s\n", attach_req.ms_network_cap_present ? "true" : "false"); m_s1ap_log->console("PDN Connectivity Request -- EPS Bearer Identity requested: %d\n", pdn_con_req.eps_bearer_id); m_s1ap_log->console("PDN Connectivity Request -- Procedure Transaction Id: %d\n", pdn_con_req.proc_transaction_id); m_s1ap_log->console("PDN Connectivity Request -- ESM Information Transfer requested: %s\n", pdn_con_req.esm_info_transfer_flag_present ? "true" : "false"); m_s1ap_log->console("Could not find M-TMSI=0x%x. Sending ID request\n",m_tmsi); - m_s1ap_log->info("Could not find M-TMSI=0x%d. Sending Id Request\n", m_tmsi); + m_s1ap_log->info("Could not find M-TMSI=0x%x. Sending Id Request\n", m_tmsi); m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); + + //We do not know the IMSI of the UE yet + //This will be removed when the Identity request is received + m_s1ap->store_tmp_ue_emm_ctx(tmp_ue_emm_ctx); + pack_identity_request(reply_buffer, ue_ecm_ctx.enb_ue_s1ap_id, ue_ecm_ctx.mme_ue_s1ap_id); *reply_flag = true; return true; From fc1629a06ef8d58bb031ffec9aeddc2620718497 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 7 Feb 2018 16:53:09 +0000 Subject: [PATCH 031/342] Fixed bug with getting EMM context in handle identity request. Attach with unknown GUTI starting to work again. --- srsepc/src/mme/s1ap_nas_transport.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 4998f68e4..bb3f9008c 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -401,6 +401,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, //We do not know the IMSI of the UE yet //This will be removed when the Identity request is received + tmp_ue_emm_ctx.mme_ue_s1ap_id = ue_ecm_ctx.mme_ue_s1ap_id; m_s1ap->store_tmp_ue_emm_ctx(tmp_ue_emm_ctx); pack_identity_request(reply_buffer, ue_ecm_ctx.enb_ue_s1ap_id, ue_ecm_ctx.mme_ue_s1ap_id); @@ -624,7 +625,13 @@ s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ //Get UE EMM context ue_emm_ctx_t ue_emm_ctx; - + if(m_s1ap->get_tmp_ue_emm_ctx(ue_ecm_ctx->mme_ue_s1ap_id, &ue_emm_ctx) == false) + { + m_s1ap_log->error("Could not find UE's temporary EMM context. MME UE S1AP Id: %d\n",ue_ecm_ctx->mme_ue_s1ap_id); + return false; + } + ue_emm_ctx.imsi=imsi; + //Get Authentication Vectors from HSS if(!m_hss->gen_auth_info_answer(imsi, ue_emm_ctx.security_ctxt.k_asme, autn, rand, ue_emm_ctx.security_ctxt.xres)) { @@ -632,7 +639,9 @@ s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ m_s1ap_log->info("User not found. IMSI %015lu\n",imsi); return false; } - + //Store UE EMM context + m_s1ap->add_new_ue_emm_ctx(ue_emm_ctx); + //Pack NAS Authentication Request in Downlink NAS Transport msg pack_authentication_request(reply_msg, ue_ecm_ctx->enb_ue_s1ap_id, ue_ecm_ctx->mme_ue_s1ap_id, autn, rand); From 386e56ef4040a18c9356a6dfaefb9990660753a0 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 7 Feb 2018 18:13:51 +0000 Subject: [PATCH 032/342] Fixed bug when GUTI is unknown but EMM context was previously present. Added function to delete EMM context. --- srsepc/hdr/mme/s1ap.h | 2 +- srsepc/src/mme/s1ap.cc | 18 +++++++++++++++++- srsepc/src/mme/s1ap_nas_transport.cc | 10 ++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index bb0140c57..323e15df2 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -87,7 +87,7 @@ public: void add_new_ue_ecm_ctx(const ue_ecm_ctx_t &ue_ecm_ctx); ue_emm_ctx_t* find_ue_emm_ctx_from_imsi(uint64_t imsi); ue_ecm_ctx_t* find_ue_ecm_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id); - bool delete_ue_emm_ctx(ue_emm_ctx_t *ue_emm_ctx); + bool delete_ue_emm_ctx(uint64_t imsi); bool delete_ue_ecm_ctx(uint32_t mme_ue_s1ap_id); void delete_ues_ecm_ctx_in_enb(uint16_t enb_id); diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 9a9ebafee..4f526ed58 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -419,6 +419,22 @@ s1ap::find_ue_ecm_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id) return it->second; } } +bool +s1ap::delete_ue_emm_ctx(uint64_t imsi) +{ + std::map::iterator ue_emm_ctx_it = m_imsi_to_ue_emm_ctx.find(imsi); + if(ue_emm_ctx_it == m_imsi_to_ue_emm_ctx.end()) + { + m_s1ap_log->info("Cannot delete UE EMM context, UE not found. IMSI: %d\n", imsi); + return false; + } + + //Delete UE context + m_imsi_to_ue_emm_ctx.erase(ue_emm_ctx_it); + delete ue_emm_ctx_it->second; + m_s1ap_log->info("Deleted UE EMM Context.\n"); + return true; +} bool s1ap::delete_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) @@ -450,7 +466,7 @@ s1ap::delete_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) //Delete UE context m_mme_ue_s1ap_id_to_ue_ecm_ctx.erase(ue_ecm_ctx_it); delete ue_ecm_ctx; - m_s1ap_log->info("Deleted UE Context.\n"); + m_s1ap_log->info("Deleted UE ECM Context.\n"); return true; } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index bb3f9008c..df33ecf3a 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -619,6 +619,16 @@ s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ for(int i=0;i<=14;i++){ imsi += id_resp.mobile_id.imsi[i]*std::pow(10,14-i); } + + //Check if EMM context already exists + ue_emm_ctx_t *ue_tmp_ptr = m_s1ap->find_ue_emm_ctx_from_imsi(imsi); + if(ue_tmp_ptr != NULL) + { + m_s1ap_log->warning("Unkonw GUTI, but UE's EMM context present.\n"); + m_s1ap->delete_ue_emm_ctx(imsi); + } + + m_s1ap_log->info("Id Response -- IMSI: %015lu\n", imsi); m_s1ap_log->console("Id Response -- IMSI: %015lu\n", imsi); ue_ecm_ctx->imsi = imsi; From 2cc717b5066c377d2d214150ebd5e2960c4d0de2 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 8 Feb 2018 13:57:30 +0000 Subject: [PATCH 033/342] Starting to check NAS intgrity of GUTI attach. --- srsepc/hdr/mme/s1ap.h | 4 ++-- srsepc/src/mme/s1ap.cc | 11 +++++----- srsepc/src/mme/s1ap_nas_transport.cc | 30 ++++++++++++++++++---------- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 323e15df2..0025a2f39 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -94,7 +94,7 @@ public: void store_tmp_ue_emm_ctx(const ue_emm_ctx_t &ue_ecm_ctx); bool get_tmp_ue_emm_ctx(uint32_t mme_ue_s1ap_id, ue_emm_ctx_t* ue_emm_ptr); - uint32_t allocate_m_tmsi(uint32_t mme_ue_s1ap_id); + uint32_t allocate_m_tmsi(uint64_t imsi); s1ap_args_t m_s1ap_args; srslte::log_filter *m_s1ap_log; @@ -103,7 +103,7 @@ public: s1ap_nas_transport* m_s1ap_nas_transport; s1ap_ctx_mngmt_proc* m_s1ap_ctx_mngmt_proc; - std::map m_tmsi_to_s1ap_id; + std::map m_tmsi_to_s1ap_id; private: s1ap(); diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 4f526ed58..9e59d9545 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -38,7 +38,8 @@ boost::mutex s1ap_instance_mutex; s1ap::s1ap(): m_s1mme(-1), - m_next_mme_ue_s1ap_id(1) + m_next_mme_ue_s1ap_id(1), + m_next_m_tmsi(0xA000) { } @@ -512,11 +513,11 @@ s1ap::activate_eps_bearer(uint32_t mme_s1ap_id, uint8_t ebi) } uint32_t -s1ap::allocate_m_tmsi(uint32_t mme_ue_s1ap_id) +s1ap::allocate_m_tmsi(uint64_t imsi) { - //uint32_t m_tmsi = m_next_m_tmsi++; - //m_tmsi_to_s1ap_id.insert(std::pair(m_tmsi,mme_ue_s1ap_id)); - uint32_t m_tmsi = 0x0123; + uint32_t m_tmsi = m_next_m_tmsi++; + m_tmsi_to_s1ap_id.insert(std::pair(m_tmsi,imsi)); + //uint32_t m_tmsi = 0x0123; return m_tmsi; } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index df33ecf3a..27b6e4bb7 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -342,7 +342,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, { //GUTI style attach uint32_t m_tmsi = attach_req.eps_mobile_id.guti.m_tmsi; - std::map::iterator it = m_s1ap->m_tmsi_to_s1ap_id.find(m_tmsi); + std::map::iterator it = m_s1ap->m_tmsi_to_s1ap_id.find(m_tmsi); if(it == m_s1ap->m_tmsi_to_s1ap_id.end()) { //Could not find IMSI from M-TMSI, send Id request @@ -411,21 +411,31 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, else{ m_s1ap_log->console("Attach Request -- Found M-TMSI: %d\n",m_tmsi); - /* - ue_ctx_t *ue_ctx_ptr = m_s1ap->find_ue_ctx(it->second); - if(ue_ctx_ptr!=NULL) + //Get UE EMM context + ue_emm_ctx_t *ue_emm_ctx = find_ue_emm_ctx_from_imsi(it->second); + if(ue_emm_ctx_ptr!=NULL) { - m_s1ap_log->console("Found UE context. IMSI: %015lu\n",ue_ctx_ptr->imsi); - m_mme_gtpc->send_create_session_request(ue_ctx_ptr->imsi, ue_ctx_ptr->mme_ue_s1ap_id); - *reply_flag = false; //No reply needed - return true; + m_s1ap_log->console("Found UE context. IMSI: %015lu\n",ue_emm_ctx_ptr->imsi); + //Check NAS integrity + bool msg_valid = false; + + if(msg_valid == true) + { + //Create session request + m_mme_gtpc->send_create_session_request(ue_ctx_ptr->imsi, ue_ctx_ptr->mme_ue_s1ap_id); + *reply_flag = false; //No reply needed + return true; + } + else + { + //NAS integrity + } } else { m_s1ap_log->error("Found M-TMSI but could not find UE context\n"); return false; } - */ } return true; } @@ -1052,7 +1062,7 @@ s1ap_nas_transport::pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *u attach_accept.guti.guti.mnc = mnc; attach_accept.guti.guti.mme_group_id = m_s1ap->m_s1ap_args.mme_group; attach_accept.guti.guti.mme_code = m_s1ap->m_s1ap_args.mme_code; - attach_accept.guti.guti.m_tmsi = m_s1ap->allocate_m_tmsi(ue_ecm_ctx->mme_ue_s1ap_id); + attach_accept.guti.guti.m_tmsi = m_s1ap->allocate_m_tmsi(ue_emm_ctx->imsi); m_s1ap_log->debug("Allocated GUTI: MCC %d, MNC %d, MME Group Id %d, MME Code 0x%x, M-TMSI 0x%x\n", attach_accept.guti.guti.mcc, attach_accept.guti.guti.mnc, From 3b90c71c661bfdc43b65736b7886d1eb7e0b6ceb Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 8 Feb 2018 14:08:02 +0000 Subject: [PATCH 034/342] changing a comment --- 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 27b6e4bb7..102c27e14 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -428,7 +428,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, } else { - //NAS integrity + //NAS integrity failed. Re-start quthentication process. } } else From 1bef5cebf67a0a906b72cabc8ff950115f0192f0 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 9 Feb 2018 10:29:40 +0000 Subject: [PATCH 035/342] small commit --- srsepc/hdr/mme/s1ap_nas_transport.h | 2 ++ srsepc/src/mme/s1ap_nas_transport.cc | 39 +++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index c38ae2bb3..b7a660e72 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -72,6 +72,8 @@ public: bool handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag); bool handle_tracking_area_update_request(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag); + bool integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_buffer_t *pdu); + 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 102c27e14..a917f133a 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -412,17 +412,17 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, m_s1ap_log->console("Attach Request -- Found M-TMSI: %d\n",m_tmsi); //Get UE EMM context - ue_emm_ctx_t *ue_emm_ctx = find_ue_emm_ctx_from_imsi(it->second); - if(ue_emm_ctx_ptr!=NULL) + ue_emm_ctx_t *ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(it->second); + if(ue_emm_ctx!=NULL) { - m_s1ap_log->console("Found UE context. IMSI: %015lu\n",ue_emm_ctx_ptr->imsi); + m_s1ap_log->console("Found UE context. IMSI: %015lu\n",ue_emm_ctx->imsi); //Check NAS integrity bool msg_valid = false; if(msg_valid == true) { //Create session request - m_mme_gtpc->send_create_session_request(ue_ctx_ptr->imsi, ue_ctx_ptr->mme_ue_s1ap_id); + m_mme_gtpc->send_create_session_request(ue_emm_ctx->imsi, ue_emm_ctx->mme_ue_s1ap_id); *reply_flag = false; //No reply needed return true; } @@ -717,6 +717,37 @@ s1ap_nas_transport::handle_tracking_area_update_request(srslte::byte_buffer_t *n } +bool +s1ap_nas_transport::integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_buffer_t *pdu) +{ + uint8_t exp_mac[4]; + uint8_t *mac = &pdu->msg[1]; + int i; + + srslte::security_128_eia1(&emm_ctx->security_ctxt.k_nas_int[16], + emm_ctx->security_ctxt.ul_nas_count, + 0, + SECURITY_DIRECTION_UPLINK, + &pdu->msg[5], + pdu->N_bytes-5, + &exp_mac[0]); + + // Check if expected mac equals the sent mac + for(i=0; i<4; i++){ + if(exp_mac[i] != mac[i]){ + m_s1ap_log->warning("Integrity check failure. Local: count=%d, [%02x %02x %02x %02x], " + "Received: count=%d, [%02x %02x %02x %02x]\n", + emm_ctx->security_ctxt.ul_nas_count, exp_mac[0], exp_mac[1], exp_mac[2], exp_mac[3], + pdu->msg[5], mac[0], mac[1], mac[2], mac[3]); + return false; + } + } + m_s1ap_log->info("Integrity check ok. Local: count=%d, Received: count=%d\n", + emm_ctx->security_ctxt.ul_nas_count, pdu->msg[5]); + 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 4222c6b9a09426168769b260e7ea469d250284c3 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Sun, 11 Feb 2018 16:38:04 +0100 Subject: [PATCH 036/342] fix mem leak in log_filter --- lib/src/common/log_filter.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/common/log_filter.cc b/lib/src/common/log_filter.cc index b498d466c..4d80a8523 100644 --- a/lib/src/common/log_filter.cc +++ b/lib/src/common/log_filter.cc @@ -91,6 +91,7 @@ void log_filter::all_log(srslte::LOG_LEVEL_ENUM level, str_ptr s_ptr(new std::string(ss.str())); logger_h->log(s_ptr); + delete(s_ptr); } } @@ -131,6 +132,7 @@ void log_filter::all_log(srslte::LOG_LEVEL_ENUM level, } str_ptr s_ptr(new std::string(ss.str())); logger_h->log(s_ptr); + delete s_ptr; } } From 1daf7b04bcd069cd0c069fe036067f85534283da Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Sun, 11 Feb 2018 19:32:07 +0100 Subject: [PATCH 037/342] add copyright header --- srsenb/src/mac/scheduler.cc | 25 +++++++++++++++++++++++++ srsenb/test/mac/scheduler_test.cc | 25 +++++++++++++++++++++++++ srsenb/test/upper/ip_test.cc | 26 ++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/srsenb/src/mac/scheduler.cc b/srsenb/src/mac/scheduler.cc index 1f1a72764..51f161d4a 100644 --- a/srsenb/src/mac/scheduler.cc +++ b/srsenb/src/mac/scheduler.cc @@ -1,3 +1,28 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2017 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of srsLTE. + * + * 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 diff --git a/srsenb/test/mac/scheduler_test.cc b/srsenb/test/mac/scheduler_test.cc index e9afd61cb..73dd531b0 100644 --- a/srsenb/test/mac/scheduler_test.cc +++ b/srsenb/test/mac/scheduler_test.cc @@ -1,3 +1,28 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2017 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of srsLTE. + * + * 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 diff --git a/srsenb/test/upper/ip_test.cc b/srsenb/test/upper/ip_test.cc index e1edf981b..8052ed4d7 100644 --- a/srsenb/test/upper/ip_test.cc +++ b/srsenb/test/upper/ip_test.cc @@ -1,3 +1,29 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2017 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of srsLTE. + * + * 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 From 59e425608fea666c3d35e0b4c7aeafa2848e6506 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Mon, 12 Feb 2018 12:44:55 +0000 Subject: [PATCH 038/342] Better fix for buffer size issue --- lib/src/upper/rlc_am.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index e4a6242fa..26f42af84 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -587,7 +587,8 @@ 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; if(pdu_space < (retx.so_end-retx.so_start)) retx.so_end = retx.so_start+pdu_space; @@ -603,10 +604,13 @@ int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t r if(lower >= retx.so_end) break; + if(pdu_space <= 2) + break; + 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; if(pdu_space < (retx.so_end-retx.so_start)) retx.so_end = retx.so_start+pdu_space; From 4cf79c1eadd0ffd24d4cb03d4d8106737971c245 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Mon, 12 Feb 2018 13:09:31 +0000 Subject: [PATCH 039/342] Initial fix for segment handling in RLC AM --- lib/src/upper/rlc_am.cc | 19 +++++++++++++------ lib/test/upper/rlc_am_stress_test.cc | 6 +++--- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 26f42af84..72fbbde17 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -1221,15 +1221,22 @@ void rlc_am::print_rx_segments() bool rlc_am::add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rlc_amd_rx_pdu_t *segment) { - // Ordered insert - std::list::iterator tmpit; - std::list::iterator it = pdu->segments.begin(); - while(it != pdu->segments.end() && it->header.so < segment->header.so) - it++; - pdu->segments.insert(it, *segment); + // Check segment offset + uint32_t n = 0; + if(!pdu->segments.empty()) { + rlc_amd_rx_pdu_t &back = pdu->segments.back(); + n = back.header.so + back.buf->N_bytes; + } + if(segment->header.so != n) { + pool->deallocate(segment->buf); + return false; + } else { + pdu->segments.push_back(*segment); + } // Check for complete uint32_t so = 0; + std::list::iterator it, tmpit; for(it = pdu->segments.begin(); it != pdu->segments.end(); it++) { if(so != it->header.so) return false; diff --git a/lib/test/upper/rlc_am_stress_test.cc b/lib/test/upper/rlc_am_stress_test.cc index 548feb818..cfed3d6e7 100644 --- a/lib/test/upper/rlc_am_stress_test.cc +++ b/lib/test/upper/rlc_am_stress_test.cc @@ -82,7 +82,7 @@ private: if(((float)rand()/RAND_MAX > fail_rate) && read>0) { rlc2->write_pdu(1, pdu->msg, opp_size); } - usleep(1000); + usleep(100); } running = false; } @@ -187,7 +187,7 @@ private: pdu->N_bytes = 1500; pdu->msg[0] = sn++; rlc->write_sdu(1, pdu); - usleep(1000); + usleep(100); } running = false; } @@ -207,7 +207,7 @@ void stress_test() log1.set_hex_limit(-1); log2.set_hex_limit(-1); - float fail_rate = 0.1; + float fail_rate = 0.01; rlc rlc1; rlc rlc2; From e18cb5ba5ba3d3561d5648f17cc2cd0f5663fcaf Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Mon, 12 Feb 2018 13:42:59 +0000 Subject: [PATCH 040/342] Fixing RLC AM tests, adding extra check for segment handling --- lib/src/upper/rlc_am.cc | 11 +++++++++++ lib/test/upper/rlc_am_stress_test.cc | 12 +++++++++--- lib/test/upper/rlc_am_test.cc | 28 ++++++++++++++-------------- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 72fbbde17..59ce25576 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -1221,6 +1221,17 @@ void rlc_am::print_rx_segments() bool rlc_am::add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rlc_amd_rx_pdu_t *segment) { + // Check for first segment + if(0 == segment->header.so) { + std::list::iterator it; + for(it = pdu->segments.begin(); it != pdu->segments.end(); it++) { + pool->deallocate(it->buf); + } + pdu->segments.clear(); + pdu->segments.push_back(*segment); + return false; + } + // Check segment offset uint32_t n = 0; if(!pdu->segments.empty()) { diff --git a/lib/test/upper/rlc_am_stress_test.cc b/lib/test/upper/rlc_am_stress_test.cc index cfed3d6e7..dc1540c96 100644 --- a/lib/test/upper/rlc_am_stress_test.cc +++ b/lib/test/upper/rlc_am_stress_test.cc @@ -139,10 +139,12 @@ class rlc_am_tester ,public thread { public: - rlc_am_tester(rlc_interface_pdcp *rlc_){ + rlc_am_tester(rlc_interface_pdcp *rlc_, std::string name_=""){ rlc = rlc_; run_enable = true; running = false; + rx_pdus = 0; + name = name_; } void stop() @@ -164,6 +166,7 @@ public: { assert(lcid == 1); byte_buffer_pool::get_instance()->deallocate(sdu); + std::cout << "rlc_am_tester " << name << " received " << rx_pdus++ << " PDUs" << std::endl; } void write_pdu_bcch_bch(byte_buffer_t *sdu) {} void write_pdu_bcch_dlsch(byte_buffer_t *sdu) {} @@ -194,6 +197,9 @@ private: bool run_enable; bool running; + long rx_pdus; + + std::string name; rlc_interface_pdcp *rlc; }; @@ -212,8 +218,8 @@ void stress_test() rlc rlc1; rlc rlc2; - rlc_am_tester tester1(&rlc1); - rlc_am_tester tester2(&rlc2); + rlc_am_tester tester1(&rlc1, "tester1"); + rlc_am_tester tester2(&rlc2, "tester2"); mac_dummy mac(&rlc1, &rlc2, fail_rate); ue_interface ue; diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index fbd013e3b..0b8c63668 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -482,17 +482,17 @@ void resegment_test_1() // Read the retx PDU from RLC1 and force resegmentation byte_buffer_t retx1; - len = rlc1.read_pdu(retx1.msg, 11); // 4 byte header + 5 data + len = rlc1.read_pdu(retx1.msg, 9); // 4 byte header + 5 data retx1.N_bytes = len; // Write the retx PDU to RLC2 rlc2.write_pdu(retx1.msg, retx1.N_bytes); - assert(9 == rlc1.get_buffer_state()); // 4 byte header + 5 data + assert(9 == rlc1.get_buffer_state()); // Read the remaining segment byte_buffer_t retx2; - len = rlc1.read_pdu(retx2.msg, 11); // 4 byte header + 5 data + len = rlc1.read_pdu(retx2.msg, 9); // 4 byte header + 5 data retx2.N_bytes = len; // Write the retx PDU to RLC2 @@ -591,16 +591,16 @@ void resegment_test_2() // Read the retx PDU from RLC1 and force resegmentation byte_buffer_t retx1; - retx1.N_bytes = rlc1.read_pdu(retx1.msg, 18); // 6 byte header + 10 data + retx1.N_bytes = rlc1.read_pdu(retx1.msg, 16); // 6 byte header + 10 data // Write the retx PDU to RLC2 rlc2.write_pdu(retx1.msg, retx1.N_bytes); - assert(16 == rlc1.get_buffer_state()); // 6 byte header + 10 data + assert(16 == rlc1.get_buffer_state()); // Read the remaining segment byte_buffer_t retx2; - retx2.N_bytes = rlc1.read_pdu(retx2.msg, 18); // 6 byte header + 10 data + retx2.N_bytes = rlc1.read_pdu(retx2.msg, 16); // 6 byte header + 10 data // Write the retx PDU to RLC2 rlc2.write_pdu(retx2.msg, retx2.N_bytes); @@ -696,14 +696,14 @@ void resegment_test_3() // Read the retx PDU from RLC1 and force resegmentation byte_buffer_t retx1; - retx1.N_bytes = rlc1.read_pdu(retx1.msg, 16); // 4 byte header + 10 data + retx1.N_bytes = rlc1.read_pdu(retx1.msg, 14); // 4 byte header + 10 data // Write the retx PDU to RLC2 rlc2.write_pdu(retx1.msg, retx1.N_bytes); // Read the remaining segment byte_buffer_t retx2; - retx2.N_bytes = rlc1.read_pdu(retx2.msg, 16); // 4 byte header + 10 data + retx2.N_bytes = rlc1.read_pdu(retx2.msg, 14); // 4 byte header + 10 data // Write the retx PDU to RLC2 rlc2.write_pdu(retx2.msg, retx2.N_bytes); @@ -799,14 +799,14 @@ void resegment_test_4() // Read the retx PDU from RLC1 and force resegmentation byte_buffer_t retx1; - retx1.N_bytes = rlc1.read_pdu(retx1.msg, 23); // 6 byte header + 15 data + retx1.N_bytes = rlc1.read_pdu(retx1.msg, 21); // 6 byte header + 15 data // Write the retx PDU to RLC2 rlc2.write_pdu(retx1.msg, retx1.N_bytes); // Read the remaining segment byte_buffer_t retx2; - retx2.N_bytes = rlc1.read_pdu(retx2.msg, 23); // 6 byte header + 15 data + retx2.N_bytes = rlc1.read_pdu(retx2.msg, 21); // 6 byte header + 15 data // Write the retx PDU to RLC2 rlc2.write_pdu(retx2.msg, retx2.N_bytes); @@ -902,14 +902,14 @@ void resegment_test_5() // Read the retx PDU from RLC1 and force resegmentation byte_buffer_t retx1; - retx1.N_bytes = rlc1.read_pdu(retx1.msg, 29); // 7 byte header + 20 data + retx1.N_bytes = rlc1.read_pdu(retx1.msg, 27); // 7 byte header + 20 data // Write the retx PDU to RLC2 rlc2.write_pdu(retx1.msg, retx1.N_bytes); // Read the remaining segment byte_buffer_t retx2; - retx2.N_bytes = rlc1.read_pdu(retx2.msg, 29); // 7 byte header + 20 data + retx2.N_bytes = rlc1.read_pdu(retx2.msg, 27); // 7 byte header + 20 data // Write the retx PDU to RLC2 rlc2.write_pdu(retx2.msg, retx2.N_bytes); @@ -1023,11 +1023,11 @@ void resegment_test_6() // Write the retx PDU to RLC2 rlc2.write_pdu(retx1.msg, retx1.N_bytes); - assert(157 == rlc1.get_buffer_state()); + assert(155 == rlc1.get_buffer_state()); // Read the remaining segment byte_buffer_t retx2; - len = rlc1.read_pdu(retx2.msg, 159); + len = rlc1.read_pdu(retx2.msg, 157); retx2.N_bytes = len; // Write the retx PDU to RLC2 From 3f7bea1af66111dcb75780c0dd1fc0bbad733687 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 12 Feb 2018 16:19:31 +0000 Subject: [PATCH 041/342] Starting to integrity check GUTI attach. Integrity failing for now. --- srsepc/hdr/mme/s1ap.h | 2 +- srsepc/hdr/mme/s1ap_nas_transport.h | 4 +- srsepc/src/mme/s1ap.cc | 3 +- srsepc/src/mme/s1ap_nas_transport.cc | 75 ++++++++++++++++++---------- 4 files changed, 54 insertions(+), 30 deletions(-) diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 0025a2f39..4015f7c70 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -103,7 +103,7 @@ public: s1ap_nas_transport* m_s1ap_nas_transport; s1ap_ctx_mngmt_proc* m_s1ap_ctx_mngmt_proc; - std::map m_tmsi_to_s1ap_id; + std::map m_tmsi_to_imsi; private: s1ap(); diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index b7a660e72..8d9b7429a 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -48,8 +48,7 @@ public: 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); bool handle_nas_attach_request( uint32_t enb_ue_s1ap_id, - const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, - const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, + srslte::byte_buffer_t *nas_msg, srslte::byte_buffer_t *reply_buffer, bool* reply_flag, struct sctp_sndrcvinfo *enb_sri); @@ -62,6 +61,7 @@ public: bool handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, + srslte::byte_buffer_t *nas_msg, srslte::byte_buffer_t *reply_buffer, bool* reply_flag, struct sctp_sndrcvinfo *enb_sri); diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 9e59d9545..4cd6f421c 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -516,7 +516,8 @@ uint32_t s1ap::allocate_m_tmsi(uint64_t imsi) { uint32_t m_tmsi = m_next_m_tmsi++; - m_tmsi_to_s1ap_id.insert(std::pair(m_tmsi,imsi)); + m_tmsi_to_imsi.insert(std::pair(m_tmsi,imsi)); + m_s1ap_log->info("Allocated M-TMSI %d,\n"); //uint32_t m_tmsi = 0x0123; return m_tmsi; } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index a917f133a..bd4865d03 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -78,8 +78,7 @@ s1ap_nas_transport::init(void) bool s1ap_nas_transport::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) { - LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req; - LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT pdn_con_req; + LIBLTE_MME_SERVICE_REQUEST_MSG_STRUCT service_req; m_s1ap_log->console("Received Initial UE Message.\n"); @@ -92,28 +91,16 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA log_unhandled_initial_ue_message_ies(init_ue); /*Check whether NAS Attach Request or Service Request*/ - uint8_t pd, msg_type; + bool mac_valid = false; + uint8_t pd, msg_type, sec_hdr_type; srslte::byte_buffer_t *nas_msg = m_pool->allocate(); memcpy(nas_msg->msg, &init_ue->NAS_PDU.buffer, init_ue->NAS_PDU.n_octets); nas_msg->N_bytes = init_ue->NAS_PDU.n_octets; + liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &pd, &msg_type); if(msg_type == LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST) { - //Get NAS Attach Request and PDN connectivity request messages - LIBLTE_ERROR_ENUM err = liblte_mme_unpack_attach_request_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &attach_req); - if(err != LIBLTE_SUCCESS){ - m_s1ap_log->error("Error unpacking NAS attach request. Error: %s\n", liblte_error_text[err]); - m_pool->deallocate(nas_msg); - return false; - } - /*Get PDN Connectivity Request*/ - err = liblte_mme_unpack_pdn_connectivity_request_msg(&attach_req.esm_msg, &pdn_con_req); - if(err != LIBLTE_SUCCESS){ - m_s1ap_log->error("Error unpacking NAS PDN Connectivity Request. Error: %s\n", liblte_error_text[err]); - m_pool->deallocate(nas_msg); - return false; - } - handle_nas_attach_request(enb_ue_s1ap_id, attach_req,pdn_con_req,reply_buffer,reply_flag, enb_sri); + handle_nas_attach_request(enb_ue_s1ap_id, nas_msg, reply_buffer,reply_flag, enb_sri); } else if(msg_type == LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST) { @@ -200,24 +187,57 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA bool s1ap_nas_transport::handle_nas_attach_request(uint32_t enb_ue_s1ap_id, - const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, - const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, + srslte::byte_buffer_t *nas_msg, srslte::byte_buffer_t *reply_buffer, bool* reply_flag, struct sctp_sndrcvinfo *enb_sri) { + LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req; + LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT pdn_con_req; + + //Get NAS Attach Request and PDN connectivity request messages + LIBLTE_ERROR_ENUM err = liblte_mme_unpack_attach_request_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &attach_req); + if(err != LIBLTE_SUCCESS){ + m_s1ap_log->error("Error unpacking NAS attach request. Error: %s\n", liblte_error_text[err]); + m_pool->deallocate(nas_msg); + return false; + } + /*Get PDN Connectivity Request*/ + err = liblte_mme_unpack_pdn_connectivity_request_msg(&attach_req.esm_msg, &pdn_con_req); + if(err != LIBLTE_SUCCESS){ + m_s1ap_log->error("Error unpacking NAS PDN Connectivity Request. Error: %s\n", liblte_error_text[err]); + m_pool->deallocate(nas_msg); + return false; + } + + //Parse the message security header + uint8 pd = 0; + uint8 msg_type = 0; + uint8 sec_hdr_type = 0; + liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &pd, &sec_hdr_type); + //Get attach type from attach request if(attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI) { m_s1ap_log->console("Attach Request -- IMSI-style attach request\n"); m_s1ap_log->info("Attach Request -- IMSI-style attach request\n"); + if(sec_hdr_type != LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS) + { + m_s1ap_log->error("Attach request -- IMSI-stlye attach request is not plain NAS\n"); + return false; + } handle_nas_imsi_attach_request(enb_ue_s1ap_id, attach_req, pdn_con_req, reply_buffer, reply_flag, enb_sri); } else if(attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI) { m_s1ap_log->console("Attach Request -- GUTI-style attach request\n"); m_s1ap_log->info("Attach Request -- GUTI-style attach request\n"); - handle_nas_guti_attach_request(enb_ue_s1ap_id, attach_req, pdn_con_req, reply_buffer, reply_flag, enb_sri); + if(sec_hdr_type != LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY) + { + m_s1ap_log->error("Attach request -- GUTI-stlye attach request is not integrity protected\n"); + return false; + } + handle_nas_guti_attach_request(enb_ue_s1ap_id, attach_req, pdn_con_req, nas_msg, reply_buffer, reply_flag, enb_sri); } else { @@ -333,17 +353,18 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, } bool -s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, +s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, + srslte::byte_buffer_t *nas_msg, srslte::byte_buffer_t *reply_buffer, bool* reply_flag, struct sctp_sndrcvinfo *enb_sri) { //GUTI style attach uint32_t m_tmsi = attach_req.eps_mobile_id.guti.m_tmsi; - std::map::iterator it = m_s1ap->m_tmsi_to_s1ap_id.find(m_tmsi); - if(it == m_s1ap->m_tmsi_to_s1ap_id.end()) + std::map::iterator it = m_s1ap->m_tmsi_to_imsi.find(m_tmsi); + if(it == m_s1ap->m_tmsi_to_imsi.end()) { //Could not find IMSI from M-TMSI, send Id request ue_emm_ctx_t tmp_ue_emm_ctx; @@ -411,6 +432,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, else{ m_s1ap_log->console("Attach Request -- Found M-TMSI: %d\n",m_tmsi); + m_s1ap_log->console("Attach Request -- IMSI: %d\n",it->second); //Get UE EMM context ue_emm_ctx_t *ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(it->second); if(ue_emm_ctx!=NULL) @@ -418,17 +440,18 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, m_s1ap_log->console("Found UE context. IMSI: %015lu\n",ue_emm_ctx->imsi); //Check NAS integrity bool msg_valid = false; - + msg_valid = integrity_check(ue_emm_ctx,nas_msg); if(msg_valid == true) { //Create session request + m_s1ap_log->console("GUTI Attach -- NAS Integrity OK."); m_mme_gtpc->send_create_session_request(ue_emm_ctx->imsi, ue_emm_ctx->mme_ue_s1ap_id); *reply_flag = false; //No reply needed return true; } else { - //NAS integrity failed. Re-start quthentication process. + //NAS integrity failed. Re-start authentication process. } } else From 913be7b29005cc35f7ad8294233bd6a764753609 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 12 Feb 2018 17:28:46 +0100 Subject: [PATCH 042/342] Fix sensor calibration on sync measure --- srsue/src/phy/phch_recv.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 6c7a8c1ea..c46316af9 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1216,9 +1216,6 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx) } mean_rsrp -= temporal_offset; } - } - - if (cnt > 2) { return MEASURE_OK; } else { return IDLE; From 81d8e7f70da56600b950ba4c5bf445b5ff8df738 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Mon, 12 Feb 2018 17:17:27 +0000 Subject: [PATCH 043/342] Fix memory leak --- lib/src/upper/rlc_am.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 59ce25576..413a02ac1 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -1309,6 +1309,7 @@ bool rlc_am::add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rlc_amd_rx_pd } handle_data_pdu(full_pdu->msg, full_pdu->N_bytes, header); + pool->deallocate(full_pdu); return true; } From bf0ff783e909ff06f16937af03254f59bb44c9cf Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 12 Feb 2018 18:24:31 +0100 Subject: [PATCH 044/342] Fixed Msg3 HARQ retx when HO --- srsue/src/upper/rrc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index ad5cf29b2..f2e410e5d 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1770,9 +1770,9 @@ void rrc::apply_rr_config_common_dl(LIBLTE_RRC_RR_CONFIG_COMMON_STRUCT *config) mac->get_config(&mac_cfg); if (config->rach_cnfg_present) { memcpy(&mac_cfg.rach, &config->rach_cnfg, sizeof(LIBLTE_RRC_RACH_CONFIG_COMMON_STRUCT)); + mac_cfg.ul_harq_params.max_harq_msg3_tx = config->rach_cnfg.max_harq_msg3_tx; } mac_cfg.prach_config_index = config->prach_cnfg.root_sequence_index; - mac_cfg.ul_harq_params.max_harq_msg3_tx = config->rach_cnfg.max_harq_msg3_tx; mac->set_config(&mac_cfg); From a1f9b35db32da4a8df52710ec50fc85c33a647b2 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Mon, 12 Feb 2018 17:24:48 +0000 Subject: [PATCH 045/342] Minor rlc_am_stress_test fix --- lib/test/upper/rlc_am_stress_test.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/test/upper/rlc_am_stress_test.cc b/lib/test/upper/rlc_am_stress_test.cc index dc1540c96..086a41bd8 100644 --- a/lib/test/upper/rlc_am_stress_test.cc +++ b/lib/test/upper/rlc_am_stress_test.cc @@ -213,7 +213,7 @@ void stress_test() log1.set_hex_limit(-1); log2.set_hex_limit(-1); - float fail_rate = 0.01; + float fail_rate = 0.1; rlc rlc1; rlc rlc2; @@ -224,7 +224,7 @@ void stress_test() ue_interface ue; rlc1.init(&tester1, &tester1, &ue, &log1, &mac, 0); - rlc2.init(&tester1, &tester1, &ue, &log2, &mac, 0); + rlc2.init(&tester2, &tester2, &ue, &log2, &mac, 0); LIBLTE_RRC_RLC_CONFIG_STRUCT cnfg; cnfg.rlc_mode = LIBLTE_RRC_RLC_MODE_AM; @@ -241,7 +241,7 @@ void stress_test() rlc2.add_bearer(1, cnfg_); tester1.start(7); - //tester2.start(7); + tester2.start(7); mac.start(); usleep(100e6); From 6f80144fbe3f873e86d9196db076e52fec71afec Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 12 Feb 2018 19:23:57 +0100 Subject: [PATCH 046/342] Revert "fix mem leak in log_filter" This reverts commit 4222c6b9a09426168769b260e7ea469d250284c3. --- lib/src/common/log_filter.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/src/common/log_filter.cc b/lib/src/common/log_filter.cc index 4d80a8523..b498d466c 100644 --- a/lib/src/common/log_filter.cc +++ b/lib/src/common/log_filter.cc @@ -91,7 +91,6 @@ void log_filter::all_log(srslte::LOG_LEVEL_ENUM level, str_ptr s_ptr(new std::string(ss.str())); logger_h->log(s_ptr); - delete(s_ptr); } } @@ -132,7 +131,6 @@ void log_filter::all_log(srslte::LOG_LEVEL_ENUM level, } str_ptr s_ptr(new std::string(ss.str())); logger_h->log(s_ptr); - delete s_ptr; } } From 4e1d2cdf05133832be551f3eb0defb9014353d0a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 00:05:52 +0100 Subject: [PATCH 047/342] Defaut in-sync for neighbour cell to true --- srsue/hdr/upper/rrc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 4ac2dfa2f..1aaf6f29b 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -87,7 +87,7 @@ class cell_t this->phy_cell = phy_cell; this->rsrp = rsrp; this->earfcn = earfcn; - in_sync = false; + in_sync = true; bzero(&sib1, sizeof(sib1)); bzero(&sib2, sizeof(sib2)); bzero(&sib3, sizeof(sib3)); From 45629d4c8641d0f611baa0164ffc76981852868a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 00:47:08 +0100 Subject: [PATCH 048/342] Changed SSS algorithm --- lib/src/phy/sync/sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/sync/sync.c b/lib/src/phy/sync/sync.c index a49311fea..c948a53d4 100644 --- a/lib/src/phy/sync/sync.c +++ b/lib/src/phy/sync/sync.c @@ -71,7 +71,7 @@ int srslte_sync_init_decim(srslte_sync_t *q, uint32_t frame_size, uint32_t max_o q->N_id_1 = 1000; q->cfo_ema_alpha = CFO_EMA_ALPHA; - q->sss_alg = SSS_PARTIAL_3; + q->sss_alg = SSS_FULL; q->detect_cp = true; q->sss_en = true; From 21edf74b06aa40b56f45d35b46343f9b26f99e43 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 00:47:22 +0100 Subject: [PATCH 049/342] Fixed Measure neighbour exiting too early --- srsue/src/phy/phch_recv.cc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index c46316af9..c8f804031 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1169,6 +1169,9 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in return ret; } } + if (ret != ERROR) { + return MEASURE_OK; + } } else { Info("INTRA: not running because offset=%d, sf_len*max_sf=%d*%d\n", offset, sf_len, max_sf); } @@ -1261,13 +1264,11 @@ void phch_recv::scell_recv::init(srslte::log *log_h, bool sic_pss_enabled, uint3 srslte_sync_set_cfo_i_enable(&sync_find, false); srslte_sync_set_cfo_pss_enable(&sync_find, true); srslte_sync_set_pss_filt_enable(&sync_find, true); - srslte_sync_set_sss_eq_enable(&sync_find, false); + srslte_sync_set_sss_eq_enable(&sync_find, true); sync_find.pss.chest_on_filter = true; - if (!sic_pss_enabled) { - sync_find.sss_channel_equalize = false; - } + sync_find.sss_channel_equalize = true; reset(); } @@ -1308,13 +1309,12 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset, if (n_id_2 != (cell.id%3) || sic_pss_enabled) { srslte_sync_set_N_id_2(&sync_find, n_id_2); - srslte_sync_find_ret_t sync_res, best_sync_res; + srslte_sync_find_ret_t sync_res; do { srslte_sync_reset(&sync_find); srslte_sync_cfo_reset(&sync_find); - best_sync_res = SRSLTE_SYNC_NOFOUND; sync_res = SRSLTE_SYNC_NOFOUND; cell_id = 0; float max_peak = -1; @@ -1327,14 +1327,13 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset, n_id_2, sf5_cnt, nof_sf/5, sync_res, srslte_sync_get_sf_idx(&sync_find), peak_idx, sync_find.peak_value); if (sync_find.peak_value > max_peak && sync_res == SRSLTE_SYNC_FOUND) { - best_sync_res = sync_res; max_sf5 = sf5_cnt; max_sf_idx = srslte_sync_get_sf_idx(&sync_find); cell_id = srslte_sync_get_cell_id(&sync_find); } } - switch(best_sync_res) { + switch(sync_res) { case SRSLTE_SYNC_ERROR: return SRSLTE_ERROR; fprintf(stderr, "Error finding correlation peak\n"); From 2cf6f96f241c6e531310ad4bf7e4999be3896a74 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 15:06:22 +0100 Subject: [PATCH 050/342] Fixes #6 AGC --- lib/include/srslte/phy/agc/agc.h | 4 ++-- lib/src/phy/agc/agc.c | 2 +- lib/src/phy/ue/ue_sync.c | 14 +++----------- srsue/hdr/phy/phch_recv.h | 1 + srsue/src/phy/phch_recv.cc | 24 ++++++++++++++++++------ srsue/src/phy/phch_worker.cc | 2 +- srsue/src/ue.cc | 11 ++++++----- srsue/src/upper/rrc.cc | 1 + 8 files changed, 33 insertions(+), 26 deletions(-) diff --git a/lib/include/srslte/phy/agc/agc.h b/lib/include/srslte/phy/agc/agc.h index 941983806..0a6bba8c1 100644 --- a/lib/include/srslte/phy/agc/agc.h +++ b/lib/include/srslte/phy/agc/agc.h @@ -42,8 +42,8 @@ #include "srslte/config.h" -#define SRSLTE_AGC_DEFAULT_TARGET 0.7 -#define SRSLTE_AGC_DEFAULT_BW (5e-1) +#define SRSLTE_AGC_DEFAULT_TARGET 0.3 +#define SRSLTE_AGC_DEFAULT_BW 0.7 typedef enum SRSLTE_API { SRSLTE_AGC_MODE_ENERGY = 0, diff --git a/lib/src/phy/agc/agc.c b/lib/src/phy/agc/agc.c index 42a6ef09d..ef09307c1 100644 --- a/lib/src/phy/agc/agc.c +++ b/lib/src/phy/agc/agc.c @@ -177,7 +177,7 @@ void srslte_agc_process(srslte_agc_t *q, cf_t *signal, uint32_t len) { gg = expf(-0.5*q->bandwidth*logf(q->y_out/q->target)); q->gain *= gg; } - DEBUG("AGC gain: %.2f (%.2f) y_out=%.3f, y=%.3f target=%.1f gg=%.2f\n", gain_db, gain_uhd_db, q->y_out, y, q->target, gg); + INFO("AGC gain: %.2f (%.2f) y_out=%.3f, y=%.3f target=%.1f gg=%.2f\n", gain_db, gain_uhd_db, q->y_out, y, q->target, gg); } } } diff --git a/lib/src/phy/ue/ue_sync.c b/lib/src/phy/ue/ue_sync.c index 7ee97c21b..d99bff89a 100644 --- a/lib/src/phy/ue/ue_sync.c +++ b/lib/src/phy/ue/ue_sync.c @@ -144,18 +144,11 @@ void srslte_ue_sync_reset(srslte_ue_sync_t *q) { int srslte_ue_sync_start_agc(srslte_ue_sync_t *q, double (set_gain_callback)(void*, double), float init_gain_value) { - uint32_t nframes; - if (q->nof_recv_sf == 1) { - nframes = 10; - } else { - nframes = 0; - } - int n = srslte_agc_init_uhd(&q->agc, SRSLTE_AGC_MODE_PEAK_AMPLITUDE, nframes, set_gain_callback, q->stream); + int n = srslte_agc_init_uhd(&q->agc, SRSLTE_AGC_MODE_PEAK_AMPLITUDE, 0, set_gain_callback, q->stream); q->do_agc = n==0?true:false; if (q->do_agc) { srslte_agc_set_gain(&q->agc, init_gain_value); - srslte_agc_set_target(&q->agc, 0.3); - srslte_agc_set_bandwidth(&q->agc, 0.8); + srslte_ue_sync_set_agc_period(q, 4); } return n; } @@ -329,7 +322,6 @@ int srslte_ue_sync_set_cell(srslte_ue_sync_t *q, srslte_cell_t cell) memcpy(&q->cell, &cell, sizeof(srslte_cell_t)); q->fft_size = srslte_symbol_sz(q->cell.nof_prb); q->sf_len = SRSLTE_SF_LEN(q->fft_size); - q->agc_period = 0; if (cell.id == 1000) { @@ -789,7 +781,7 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE if (q->do_agc && (q->agc_period == 0 || (q->agc_period && (q->frame_total_cnt%q->agc_period) == 0))) { - srslte_agc_process(&q->agc, input_buffer[0], q->sf_len); + srslte_agc_process(&q->agc, input_buffer[0], q->sf_len); } /* Track PSS/SSS around the expected PSS position diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index efe46d63e..66c3342fb 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -125,6 +125,7 @@ private: float get_last_gain(); float get_last_cfo(); void set_N_id_2(int N_id_2); + void set_agc_enable(bool enable); ret_code run(srslte_cell_t *cell); private: diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index c8f804031..bf09f5f34 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -174,6 +174,16 @@ bool phch_recv::wait_radio_reset() { void phch_recv::set_agc_enable(bool enable) { do_agc = enable; + if (do_agc) { + if (running && radio_h) { + srslte_ue_sync_start_agc(&ue_sync, callback_set_rx_gain, radio_h->get_rx_gain()); + search_p.set_agc_enable(true); + } else { + fprintf(stderr, "Error setting AGC: PHY not initiatec\n"); + } + } else { + fprintf(stderr, "Error stopping AGC: not implemented\n"); + } } void phch_recv::set_time_adv_sec(float _time_adv_sec) @@ -832,6 +842,14 @@ float phch_recv::search::get_last_cfo() return srslte_ue_sync_get_cfo(&ue_mib_sync.ue_sync); } +void phch_recv::search::set_agc_enable(bool enable) { + if (enable) { + srslte_ue_sync_start_agc(&ue_mib_sync.ue_sync, callback_set_rx_gain, p->radio_h->get_rx_gain()); + } else { + fprintf(stderr, "Error stop AGC not implemented\n"); + } +} + phch_recv::search::ret_code phch_recv::search::run(srslte_cell_t *cell) { @@ -891,11 +909,6 @@ phch_recv::search::ret_code phch_recv::search::run(srslte_cell_t *cell) // Set options defined in expert section p->set_ue_sync_opts(&ue_mib_sync.ue_sync, cfo); - // Start AGC after initial cell search - if (p->do_agc) { - srslte_ue_sync_start_agc(&ue_mib_sync.ue_sync, callback_set_rx_gain, p->radio_h->get_rx_gain()); - } - srslte_ue_sync_reset(&ue_mib_sync.ue_sync); /* Find and decode MIB */ @@ -1011,7 +1024,6 @@ phch_recv::sfn_sync::ret_code phch_recv::sfn_sync::run_subframe(srslte_cell_t *c Info("SYNC: DONE, TTI=%d, sfn_offset=%d\n", *tti_cnt, sfn_offset); } - srslte_ue_sync_set_agc_period(ue_sync, 20); srslte_ue_sync_decode_sss_on_track(ue_sync, true); reset(); return SFN_FOUND; diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index f7e1381f8..a4e6eeb47 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -1436,7 +1436,7 @@ void phch_worker::update_measurements() dl_metrics.rsrp = phy->avg_rsrp_dbm; dl_metrics.rsrq = phy->avg_rsrq_db; dl_metrics.rssi = phy->avg_rssi_dbm; - dl_metrics.pathloss = phy->pathloss; + dl_metrics.pathloss = phy->get_radio()->get_rx_gain(); dl_metrics.sinr = phy->avg_snr_db; dl_metrics.turbo_iters = srslte_pdsch_last_noi(&ue_dl.pdsch); phy->set_dl_metrics(dl_metrics); diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index a9277e62c..611bac620 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -130,11 +130,7 @@ bool ue::init(all_args_t *args_) // Init layers - if (args->rf.rx_gain < 0) { - phy.set_agc_enable(true); - } - - // PHY initis in background, start before radio + // PHY inits in background, start before radio args->expert.phy.nof_rx_ant = args->rf.nof_rx_ant; phy.init(&radio, &mac, &rrc, phy_log, &args->expert.phy); @@ -222,6 +218,11 @@ bool ue::init(all_args_t *args_) phy.wait_initialize(); phy.configure_ul_params(); + // Enable AGC once PHY is initialized + if (args->rf.rx_gain < 0) { + phy.set_agc_enable(true); + } + printf("...\n"); nas.attach_request(); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index f2e410e5d..f93401fc5 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1062,6 +1062,7 @@ bool rrc::ho_prepare() { int target_cell_idx = find_neighbour_cell(serving_cell->earfcn, mob_reconf.mob_ctrl_info.target_pci); if (target_cell_idx < 0) { + rrc_log->console("Received HO command to unknown PCI=%d\n", mob_reconf.mob_ctrl_info.target_pci); rrc_log->error("Could not find target cell earfcn=%d, pci=%d\n", serving_cell->earfcn, mob_reconf.mob_ctrl_info.target_pci); return false; } From a568db3b04c11d43deebf7a705b46bf6a7cc31a4 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 18:03:44 +0100 Subject: [PATCH 051/342] Fixed PRACH HS=TRUE bug and indentation --- lib/src/phy/phch/prach.c | 613 +++++++++++++++++++-------------------- 1 file changed, 298 insertions(+), 315 deletions(-) diff --git a/lib/src/phy/phch/prach.c b/lib/src/phy/phch/prach.c index ffd8b51e7..74356417a 100644 --- a/lib/src/phy/phch/prach.c +++ b/lib/src/phy/phch/prach.c @@ -57,185 +57,177 @@ float save_corr[4096]; uint32_t prach_Tcp[5] = {3168, 21024, 6240, 21024, 448}; // Table 5.7.1-1 T_seq for preamble formats -uint32_t prach_Tseq[5] = {24576, 24576, 2*24576, 2*24576, 4096}; +uint32_t prach_Tseq[5] = {24576, 24576, 2 * 24576, 2 * 24576, 4096}; // Table 5.7.2-2 - N_cs values for unrestricted sets -uint32_t prach_Ncs_unrestricted[16] = {0,13,15,18,22,26,32,38,46,59,76,93,119,167,279,419}; +uint32_t prach_Ncs_unrestricted[16] = {0, 13, 15, 18, 22, 26, 32, 38, 46, 59, 76, 93, 119, 167, 279, 419}; #define MAX_N_zc 839 // Table 5.7.2-2 - N_cs values for restricted sets -uint32_t prach_Ncs_restricted[15] = {15,18,22,26,32,38,46,55,68,82,100,128,158,202,237}; +uint32_t prach_Ncs_restricted[15] = {15, 18, 22, 26, 32, 38, 46, 55, 68, 82, 100, 128, 158, 202, 237}; // Table 5.7.2-3 - N_cs values for preamble format 4 -uint32_t prach_Ncs_format4[7] = {2,4,6,8,10,12,15}; +uint32_t prach_Ncs_format4[7] = {2, 4, 6, 8, 10, 12, 15}; // Table 5.7.2-4 - Root ZC sequence order uint32_t prach_zc_roots[838] = { - 129, 710, 140, 699, 120, 719, 210, 629, 168, 671, 84, 755, - 105, 734, 93, 746, 70, 769, 60, 779, 2, 837, 1, 838, - 56, 783, 112, 727, 148, 691, 80, 759, 42, 797, 40, 799, - 35, 804, 73, 766, 146, 693, 31, 808, 28, 811, 30, 809, - 27, 812, 29, 810, 24, 815, 48, 791, 68, 771, 74, 765, - 178, 661, 136, 703, 86, 753, 78, 761, 43, 796, 39, 800, - 20, 819, 21, 818, 95, 744, 202, 637, 190, 649, 181, 658, - 137, 702, 125, 714, 151, 688, 217, 622, 128, 711, 142, 697, - 122, 717, 203, 636, 118, 721, 110, 729, 89, 750, 103, 736, - 61, 778, 55, 784, 15, 824, 14, 825, 12, 827, 23, 816, - 34, 805, 37, 802, 46, 793, 207, 632, 179, 660, 145, 694, - 130, 709, 223, 616, 228, 611, 227, 612, 132, 707, 133, 706, - 143, 696, 135, 704, 161, 678, 201, 638, 173, 666, 106, 733, - 83, 756, 91, 748, 66, 773, 53, 786, 10, 829, 9, 830, - 7, 832, 8, 831, 16, 823, 47, 792, 64, 775, 57, 782, - 104, 735, 101, 738, 108, 731, 208, 631, 184, 655, 197, 642, - 191, 648, 121, 718, 141, 698, 149, 690, 216, 623, 218, 621, - 152, 687, 144, 695, 134, 705, 138, 701, 199, 640, 162, 677, - 176, 663, 119, 720, 158, 681, 164, 675, 174, 665, 171, 668, - 170, 669, 87, 752, 169, 670, 88, 751, 107, 732, 81, 758, - 82, 757, 100, 739, 98, 741, 71, 768, 59, 780, 65, 774, - 50, 789, 49, 790, 26, 813, 17, 822, 13, 826, 6, 833, - 5, 834, 33, 806, 51, 788, 75, 764, 99, 740, 96, 743, - 97, 742, 166, 673, 172, 667, 175, 664, 187, 652, 163, 676, - 185, 654, 200, 639, 114, 725, 189, 650, 115, 724, 194, 645, - 195, 644, 192, 647, 182, 657, 157, 682, 156, 683, 211, 628, - 154, 685, 123, 716, 139, 700, 212, 627, 153, 686, 213, 626, - 215, 624, 150, 689, 225, 614, 224, 615, 221, 618, 220, 619, - 127, 712, 147, 692, 124, 715, 193, 646, 205, 634, 206, 633, - 116, 723, 160, 679, 186, 653, 167, 672, 79, 760, 85, 754, - 77, 762, 92, 747, 58, 781, 62, 777, 69, 770, 54, 785, - 36, 803, 32, 807, 25, 814, 18, 821, 11, 828, 4, 835, - 3, 836, 19, 820, 22, 817, 41, 798, 38, 801, 44, 795, - 52, 787, 45, 794, 63, 776, 67, 772, 72, 767, 76, 763, - 94, 745, 102, 737, 90, 749, 109, 730, 165, 674, 111, 728, - 209, 630, 204, 635, 117, 722, 188, 651, 159, 680, 198, 641, - 113, 726, 183, 656, 180, 659, 177, 662, 196, 643, 155, 684, - 214, 625, 126, 713, 131, 708, 219, 620, 222, 617, 226, 613, - 230, 609, 232, 607, 262, 577, 252, 587, 418, 421, 416, 423, - 413, 426, 411, 428, 376, 463, 395, 444, 283, 556, 285, 554, - 379, 460, 390, 449, 363, 476, 384, 455, 388, 451, 386, 453, - 361, 478, 387, 452, 360, 479, 310, 529, 354, 485, 328, 511, - 315, 524, 337, 502, 349, 490, 335, 504, 324, 515, 323, 516, - 320, 519, 334, 505, 359, 480, 295, 544, 385, 454, 292, 547, - 291, 548, 381, 458, 399, 440, 380, 459, 397, 442, 369, 470, - 377, 462, 410, 429, 407, 432, 281, 558, 414, 425, 247, 592, - 277, 562, 271, 568, 272, 567, 264, 575, 259, 580, 237, 602, - 239, 600, 244, 595, 243, 596, 275, 564, 278, 561, 250, 589, - 246, 593, 417, 422, 248, 591, 394, 445, 393, 446, 370, 469, - 365, 474, 300, 539, 299, 540, 364, 475, 362, 477, 298, 541, - 312, 527, 313, 526, 314, 525, 353, 486, 352, 487, 343, 496, - 327, 512, 350, 489, 326, 513, 319, 520, 332, 507, 333, 506, - 348, 491, 347, 492, 322, 517, 330, 509, 338, 501, 341, 498, - 340, 499, 342, 497, 301, 538, 366, 473, 401, 438, 371, 468, - 408, 431, 375, 464, 249, 590, 269, 570, 238, 601, 234, 605, - 257, 582, 273, 566, 255, 584, 254, 585, 245, 594, 251, 588, - 412, 427, 372, 467, 282, 557, 403, 436, 396, 443, 392, 447, - 391, 448, 382, 457, 389, 450, 294, 545, 297, 542, 311, 528, - 344, 495, 345, 494, 318, 521, 331, 508, 325, 514, 321, 518, - 346, 493, 339, 500, 351, 488, 306, 533, 289, 550, 400, 439, - 378, 461, 374, 465, 415, 424, 270, 569, 241, 598, 231, 608, - 260, 579, 268, 571, 276, 563, 409, 430, 398, 441, 290, 549, - 304, 535, 308, 531, 358, 481, 316, 523, 293, 546, 288, 551, - 284, 555, 368, 471, 253, 586, 256, 583, 263, 576, 242, 597, - 274, 565, 402, 437, 383, 456, 357, 482, 329, 510, 317, 522, - 307, 532, 286, 553, 287, 552, 266, 573, 261, 578, 236, 603, - 303, 536, 356, 483, 355, 484, 405, 434, 404, 435, 406, 433, - 235, 604, 267, 572, 302, 537, 309, 530, 265, 574, 233, 606, - 367, 472, 296, 543, 336, 503, 305, 534, 373, 466, 280, 559, - 279, 560, 419, 420, 240, 599, 258, 581, 229, 610}; + 129, 710, 140, 699, 120, 719, 210, 629, 168, 671, 84, 755, + 105, 734, 93, 746, 70, 769, 60, 779, 2, 837, 1, 838, + 56, 783, 112, 727, 148, 691, 80, 759, 42, 797, 40, 799, + 35, 804, 73, 766, 146, 693, 31, 808, 28, 811, 30, 809, + 27, 812, 29, 810, 24, 815, 48, 791, 68, 771, 74, 765, + 178, 661, 136, 703, 86, 753, 78, 761, 43, 796, 39, 800, + 20, 819, 21, 818, 95, 744, 202, 637, 190, 649, 181, 658, + 137, 702, 125, 714, 151, 688, 217, 622, 128, 711, 142, 697, + 122, 717, 203, 636, 118, 721, 110, 729, 89, 750, 103, 736, + 61, 778, 55, 784, 15, 824, 14, 825, 12, 827, 23, 816, + 34, 805, 37, 802, 46, 793, 207, 632, 179, 660, 145, 694, + 130, 709, 223, 616, 228, 611, 227, 612, 132, 707, 133, 706, + 143, 696, 135, 704, 161, 678, 201, 638, 173, 666, 106, 733, + 83, 756, 91, 748, 66, 773, 53, 786, 10, 829, 9, 830, + 7, 832, 8, 831, 16, 823, 47, 792, 64, 775, 57, 782, + 104, 735, 101, 738, 108, 731, 208, 631, 184, 655, 197, 642, + 191, 648, 121, 718, 141, 698, 149, 690, 216, 623, 218, 621, + 152, 687, 144, 695, 134, 705, 138, 701, 199, 640, 162, 677, + 176, 663, 119, 720, 158, 681, 164, 675, 174, 665, 171, 668, + 170, 669, 87, 752, 169, 670, 88, 751, 107, 732, 81, 758, + 82, 757, 100, 739, 98, 741, 71, 768, 59, 780, 65, 774, + 50, 789, 49, 790, 26, 813, 17, 822, 13, 826, 6, 833, + 5, 834, 33, 806, 51, 788, 75, 764, 99, 740, 96, 743, + 97, 742, 166, 673, 172, 667, 175, 664, 187, 652, 163, 676, + 185, 654, 200, 639, 114, 725, 189, 650, 115, 724, 194, 645, + 195, 644, 192, 647, 182, 657, 157, 682, 156, 683, 211, 628, + 154, 685, 123, 716, 139, 700, 212, 627, 153, 686, 213, 626, + 215, 624, 150, 689, 225, 614, 224, 615, 221, 618, 220, 619, + 127, 712, 147, 692, 124, 715, 193, 646, 205, 634, 206, 633, + 116, 723, 160, 679, 186, 653, 167, 672, 79, 760, 85, 754, + 77, 762, 92, 747, 58, 781, 62, 777, 69, 770, 54, 785, + 36, 803, 32, 807, 25, 814, 18, 821, 11, 828, 4, 835, + 3, 836, 19, 820, 22, 817, 41, 798, 38, 801, 44, 795, + 52, 787, 45, 794, 63, 776, 67, 772, 72, 767, 76, 763, + 94, 745, 102, 737, 90, 749, 109, 730, 165, 674, 111, 728, + 209, 630, 204, 635, 117, 722, 188, 651, 159, 680, 198, 641, + 113, 726, 183, 656, 180, 659, 177, 662, 196, 643, 155, 684, + 214, 625, 126, 713, 131, 708, 219, 620, 222, 617, 226, 613, + 230, 609, 232, 607, 262, 577, 252, 587, 418, 421, 416, 423, + 413, 426, 411, 428, 376, 463, 395, 444, 283, 556, 285, 554, + 379, 460, 390, 449, 363, 476, 384, 455, 388, 451, 386, 453, + 361, 478, 387, 452, 360, 479, 310, 529, 354, 485, 328, 511, + 315, 524, 337, 502, 349, 490, 335, 504, 324, 515, 323, 516, + 320, 519, 334, 505, 359, 480, 295, 544, 385, 454, 292, 547, + 291, 548, 381, 458, 399, 440, 380, 459, 397, 442, 369, 470, + 377, 462, 410, 429, 407, 432, 281, 558, 414, 425, 247, 592, + 277, 562, 271, 568, 272, 567, 264, 575, 259, 580, 237, 602, + 239, 600, 244, 595, 243, 596, 275, 564, 278, 561, 250, 589, + 246, 593, 417, 422, 248, 591, 394, 445, 393, 446, 370, 469, + 365, 474, 300, 539, 299, 540, 364, 475, 362, 477, 298, 541, + 312, 527, 313, 526, 314, 525, 353, 486, 352, 487, 343, 496, + 327, 512, 350, 489, 326, 513, 319, 520, 332, 507, 333, 506, + 348, 491, 347, 492, 322, 517, 330, 509, 338, 501, 341, 498, + 340, 499, 342, 497, 301, 538, 366, 473, 401, 438, 371, 468, + 408, 431, 375, 464, 249, 590, 269, 570, 238, 601, 234, 605, + 257, 582, 273, 566, 255, 584, 254, 585, 245, 594, 251, 588, + 412, 427, 372, 467, 282, 557, 403, 436, 396, 443, 392, 447, + 391, 448, 382, 457, 389, 450, 294, 545, 297, 542, 311, 528, + 344, 495, 345, 494, 318, 521, 331, 508, 325, 514, 321, 518, + 346, 493, 339, 500, 351, 488, 306, 533, 289, 550, 400, 439, + 378, 461, 374, 465, 415, 424, 270, 569, 241, 598, 231, 608, + 260, 579, 268, 571, 276, 563, 409, 430, 398, 441, 290, 549, + 304, 535, 308, 531, 358, 481, 316, 523, 293, 546, 288, 551, + 284, 555, 368, 471, 253, 586, 256, 583, 263, 576, 242, 597, + 274, 565, 402, 437, 383, 456, 357, 482, 329, 510, 317, 522, + 307, 532, 286, 553, 287, 552, 266, 573, 261, 578, 236, 603, + 303, 536, 356, 483, 355, 484, 405, 434, 404, 435, 406, 433, + 235, 604, 267, 572, 302, 537, 309, 530, 265, 574, 233, 606, + 367, 472, 296, 543, 336, 503, 305, 534, 373, 466, 280, 559, + 279, 560, 419, 420, 240, 599, 258, 581, 229, 610}; // Table 5.7.2-5 - Root ZC sequence order for preamble format 4 uint32_t prach_zc_roots_format4[138] = { - 1, 138, 2, 137, 3, 136, 4, 135, 5, 134, 6, 133, - 7, 132, 8, 131, 9, 130, 10, 129, 11, 128, 12, 127, - 13, 126, 14, 125, 15, 124, 16, 123, 17, 122, 18, 121, - 19, 120, 20, 119, 21, 118, 22, 117, 23, 116, 24, 115, - 25, 114, 26, 113, 27, 112, 28, 111, 29, 110, 30, 109, - 31, 108, 32, 107, 33, 106, 34, 105, 35, 104, 36, 103, - 37, 102, 38, 101, 39, 100, 40, 99, 41, 98, 42, 97, - 43, 96, 44, 95, 45, 94, 46, 93, 47, 92, 48, 91, - 49, 90, 50, 89, 51, 88, 52, 87, 53, 86, 54, 85, - 55, 84, 56, 83, 57, 82, 58, 81, 59, 80, 60, 79, - 61, 78, 62, 77, 63, 76, 64, 75, 65, 74, 66, 73, - 67, 72, 68, 71, 69, 70}; - - + 1, 138, 2, 137, 3, 136, 4, 135, 5, 134, 6, 133, + 7, 132, 8, 131, 9, 130, 10, 129, 11, 128, 12, 127, + 13, 126, 14, 125, 15, 124, 16, 123, 17, 122, 18, 121, + 19, 120, 20, 119, 21, 118, 22, 117, 23, 116, 24, 115, + 25, 114, 26, 113, 27, 112, 28, 111, 29, 110, 30, 109, + 31, 108, 32, 107, 33, 106, 34, 105, 35, 104, 36, 103, + 37, 102, 38, 101, 39, 100, 40, 99, 41, 98, 42, 97, + 43, 96, 44, 95, 45, 94, 46, 93, 47, 92, 48, 91, + 49, 90, 50, 89, 51, 88, 52, 87, 53, 86, 54, 85, + 55, 84, 56, 83, 57, 82, 58, 81, 59, 80, 60, 79, + 61, 78, 62, 77, 63, 76, 64, 75, 65, 74, 66, 73, + 67, 72, 68, 71, 69, 70}; + srslte_prach_sf_config_t prach_sf_config[16] = { - {1, {1, 0, 0, 0, 0}}, - {1, {4, 0, 0, 0, 0}}, - {1, {7, 0, 0, 0, 0}}, - {1, {1, 0, 0, 0, 0}}, - {1, {4, 0, 0, 0, 0}}, - {1, {7, 0, 0, 0, 0}}, - {2, {1, 6, 0, 0, 0}}, - {2, {2, 7, 0, 0, 0}}, - {2, {3, 8, 0, 0, 0}}, - {3, {1, 4, 7, 0, 0}}, - {3, {2, 5, 8, 0, 0}}, - {3, {3, 6, 9, 0, 0}}, - {5, {0, 2, 4, 6, 8}}, - {5, {1, 3, 5, 7, 9}}, - {-1, {0, 0, 0, 0, 0}}, // this means all subframes - {1, {9, 0, 0, 0, 0}}}; + {1, {1, 0, 0, 0, 0}}, + {1, {4, 0, 0, 0, 0}}, + {1, {7, 0, 0, 0, 0}}, + {1, {1, 0, 0, 0, 0}}, + {1, {4, 0, 0, 0, 0}}, + {1, {7, 0, 0, 0, 0}}, + {2, {1, 6, 0, 0, 0}}, + {2, {2, 7, 0, 0, 0}}, + {2, {3, 8, 0, 0, 0}}, + {3, {1, 4, 7, 0, 0}}, + {3, {2, 5, 8, 0, 0}}, + {3, {3, 6, 9, 0, 0}}, + {5, {0, 2, 4, 6, 8}}, + {5, {1, 3, 5, 7, 9}}, + {-1, {0, 0, 0, 0, 0}}, // this means all subframes + {1, {9, 0, 0, 0, 0}}}; uint32_t srslte_prach_get_preamble_format(uint32_t config_idx) { - return config_idx/16; + return config_idx / 16; } srslte_prach_sfn_t srslte_prach_get_sfn(uint32_t config_idx) { - if ((config_idx%16)<3 || (config_idx%16)==15) { + if ((config_idx % 16) < 3 || (config_idx % 16) == 15) { return SRSLTE_PRACH_SFN_EVEN; } else { - return SRSLTE_PRACH_SFN_ANY; + return SRSLTE_PRACH_SFN_ANY; } } /* Returns true if current_tti is a valid opportunity for PRACH transmission and the is an allowed subframe, * or allowed_subframe == -1 */ -bool srslte_prach_tti_opportunity(srslte_prach_t *p, uint32_t current_tti, int allowed_subframe) -{ - uint32_t config_idx = p->config_idx; +bool srslte_prach_tti_opportunity(srslte_prach_t *p, uint32_t current_tti, int allowed_subframe) { + uint32_t config_idx = p->config_idx; // Get SFN and sf_idx from the PRACH configuration index - srslte_prach_sfn_t prach_sfn = srslte_prach_get_sfn(config_idx); + srslte_prach_sfn_t prach_sfn = srslte_prach_get_sfn(config_idx); // This is the only option which provides always an opportunity for PRACH transmission. - if(config_idx == 14) { + if (config_idx == 14) { return true; } - if ((prach_sfn == SRSLTE_PRACH_SFN_EVEN && ((current_tti/10)%2)==0) || - prach_sfn == SRSLTE_PRACH_SFN_ANY) - { + if ((prach_sfn == SRSLTE_PRACH_SFN_EVEN && ((current_tti / 10) % 2) == 0) || + prach_sfn == SRSLTE_PRACH_SFN_ANY) { srslte_prach_sf_config_t sf_config; srslte_prach_sf_config(config_idx, &sf_config); - for (int i=0;i v_max){ + if (v > v_max) { // Get a new root sequence - if(4 == p->f){ - u = prach_zc_roots_format4[(p->rsi + p->N_roots)%138]; - }else{ - u = prach_zc_roots[(p->rsi + p->N_roots)%838]; + if (4 == p->f) { + u = prach_zc_roots_format4[(p->rsi + p->N_roots) % 138]; + } else { + u = prach_zc_roots[(p->rsi + p->N_roots) % 838]; } - for(int j=0;jN_zc;j++){ - double phase = -M_PI*u*j*(j+1)/p->N_zc; - root[j] = cexp(phase*I); + for (int j = 0; j < p->N_zc; j++) { + double phase = -M_PI * u * j * (j + 1) / p->N_zc; + root[j] = cexp(phase * I); } p->root_seqs_idx[p->N_roots++] = i; // Determine v_max - if(p->hs){ + if (p->hs) { // High-speed cell - for(p_=1; p_<=p->N_zc; p_++){ - if(((p_*u) % p->N_zc) == 1) - break; + for (p_ = 1; p_ <= p->N_zc; p_++) { + if (((p_ * u) % p->N_zc) == 1) + break; } - if(p_ < p->N_zc/2){ - d_u = p_; - }else{ - d_u = p->N_zc - p_; + if (p_ < p->N_zc / 2) { + d_u = p_; + } else { + d_u = p->N_zc - p_; } - if(d_u >= p->N_cs && d_u < p->N_zc/3){ - N_shift = d_u/p->N_cs; - d_start = 2*d_u + N_shift*p->N_cs; - N_group = p->N_zc/d_start; - N_neg_shift = (p->N_zc - 2*d_u - N_group*d_start)/p->N_cs; - if(N_neg_shift < 0) - N_neg_shift = 0; - }else{ - N_shift = (p->N_zc - 2*d_u)/p->N_cs; - d_start = p->N_zc - 2*d_u + N_shift*p->N_cs; - N_group = d_u/d_start; - N_neg_shift = (d_u - N_group*d_start)/p->N_cs; - if(N_neg_shift < 0) - N_neg_shift = 0; - if(N_neg_shift > N_shift) - N_neg_shift = N_shift; + if (d_u >= p->N_cs && d_u < p->N_zc / 3) { + N_shift = d_u / p->N_cs; + d_start = 2 * d_u + N_shift * p->N_cs; + N_group = p->N_zc / d_start; + if (p->N_zc > 2 * d_u + N_group * d_start) { + N_neg_shift = (p->N_zc - 2 * d_u - N_group * d_start) / p->N_cs; + } else { + N_neg_shift = 0; + } + } else if (p->N_zc / 3 <= d_u && d_u <= (p->N_zc - p->N_cs) / 2) { + N_shift = (p->N_zc - 2 * d_u) / p->N_cs; + d_start = p->N_zc - 2 * d_u + N_shift * p->N_cs; + N_group = d_u / d_start; + N_neg_shift = (d_u - N_group * d_start) / p->N_cs; + if (N_neg_shift < 0) + N_neg_shift = 0; + if (N_neg_shift > N_shift) + N_neg_shift = N_shift; + } else { + N_shift = 0; } - v_max = N_shift*N_group + N_neg_shift - 1; - if(v_max < 0){ + v_max = N_shift * N_group + N_neg_shift - 1; + if (v_max < 0) { v_max = 0; } - }else{ + } else { // Normal cell - if(0 == p->N_cs){ + if (0 == p->N_cs) { v_max = 0; - }else{ - v_max = (p->N_zc/p->N_cs)-1; + } else { + v_max = (p->N_zc / p->N_cs) - 1; } } - v=0; + v = 0; } // Shift root and add to set - if(p->hs){ - if(N_shift==0){ + if (p->hs) { + if (N_shift == 0) { C_v = 0; - }else{ - C_v = d_start*floor(v/N_shift) + (v % N_shift)*p->N_cs; + } else { + C_v = d_start * floor(v / N_shift) + (v % N_shift) * p->N_cs; } - }else{ - C_v = v*p->N_cs; + } else { + C_v = v * p->N_cs; + } + if (i == 46) { + printf("i=%d, C_v=%d\n", i, C_v); } - for(int j=0;jN_zc;j++){ - p->seqs[i][j] = root[(j+C_v) % p->N_zc]; + for (int j = 0; j < p->N_zc; j++) { + p->seqs[i][j] = root[(j + C_v) % p->N_zc]; } v++; @@ -329,69 +328,66 @@ int srslte_prach_gen_seqs(srslte_prach_t *p) return 0; } -int srslte_prach_init_cfg(srslte_prach_t *p, srslte_prach_cfg_t *cfg, uint32_t nof_prb) -{ +int srslte_prach_init_cfg(srslte_prach_t *p, srslte_prach_cfg_t *cfg, uint32_t nof_prb) { if (srslte_prach_init(p, srslte_symbol_sz(nof_prb))) { return -1; } return srslte_prach_set_cell(p, - srslte_symbol_sz(nof_prb), - cfg->config_idx, - cfg->root_seq_idx, - cfg->hs_flag, - cfg->zero_corr_zone); + srslte_symbol_sz(nof_prb), + cfg->config_idx, + cfg->root_seq_idx, + cfg->hs_flag, + cfg->zero_corr_zone); } -int srslte_prach_init(srslte_prach_t *p, uint32_t max_N_ifft_ul) -{ +int srslte_prach_init(srslte_prach_t *p, uint32_t max_N_ifft_ul) { int ret = SRSLTE_ERROR; - if(p != NULL && - max_N_ifft_ul < 2049) - { + if (p != NULL && + max_N_ifft_ul < 2049) { bzero(p, sizeof(srslte_prach_t)); p->max_N_ifft_ul = max_N_ifft_ul; // Set up containers - p->prach_bins = srslte_vec_malloc(sizeof(cf_t)*MAX_N_zc); - p->corr_spec = srslte_vec_malloc(sizeof(cf_t)*MAX_N_zc); - p->corr = srslte_vec_malloc(sizeof(float)*MAX_N_zc); + p->prach_bins = srslte_vec_malloc(sizeof(cf_t) * MAX_N_zc); + p->corr_spec = srslte_vec_malloc(sizeof(cf_t) * MAX_N_zc); + p->corr = srslte_vec_malloc(sizeof(float) * MAX_N_zc); // Set up ZC FFTS - if(srslte_dft_plan(&p->zc_fft, MAX_N_zc, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)){ + if (srslte_dft_plan(&p->zc_fft, MAX_N_zc, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) { return SRSLTE_ERROR; } srslte_dft_plan_set_mirror(&p->zc_fft, false); srslte_dft_plan_set_norm(&p->zc_fft, true); - if(srslte_dft_plan(&p->zc_ifft, MAX_N_zc, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)){ + if (srslte_dft_plan(&p->zc_ifft, MAX_N_zc, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) { return SRSLTE_ERROR; } srslte_dft_plan_set_mirror(&p->zc_ifft, false); srslte_dft_plan_set_norm(&p->zc_ifft, false); - uint32_t fft_size_alloc = max_N_ifft_ul * DELTA_F/DELTA_F_RA; + uint32_t fft_size_alloc = max_N_ifft_ul * DELTA_F / DELTA_F_RA; - p->ifft_in = (cf_t*)srslte_vec_malloc(fft_size_alloc*sizeof(cf_t)); - p->ifft_out = (cf_t*)srslte_vec_malloc(fft_size_alloc*sizeof(cf_t)); - if(srslte_dft_plan(&p->ifft, fft_size_alloc, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) { + p->ifft_in = (cf_t *) srslte_vec_malloc(fft_size_alloc * sizeof(cf_t)); + p->ifft_out = (cf_t *) srslte_vec_malloc(fft_size_alloc * sizeof(cf_t)); + if (srslte_dft_plan(&p->ifft, fft_size_alloc, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) { fprintf(stderr, "Error creating DFT plan\n"); return -1; } srslte_dft_plan_set_mirror(&p->ifft, true); srslte_dft_plan_set_norm(&p->ifft, true); - if(srslte_dft_plan(&p->fft, fft_size_alloc, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)){ + if (srslte_dft_plan(&p->fft, fft_size_alloc, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) { fprintf(stderr, "Error creating DFT plan\n"); return -1; } - - p->signal_fft = srslte_vec_malloc(sizeof(cf_t)*fft_size_alloc); + + p->signal_fft = srslte_vec_malloc(sizeof(cf_t) * fft_size_alloc); if (!p->signal_fft) { fprintf(stderr, "Error allocating memory\n"); - return -1; + return -1; } - + srslte_dft_plan_set_mirror(&p->fft, true); srslte_dft_plan_set_norm(&p->fft, false); @@ -403,20 +399,17 @@ int srslte_prach_init(srslte_prach_t *p, uint32_t max_N_ifft_ul) return ret; } - int srslte_prach_set_cell(srslte_prach_t *p, - uint32_t N_ifft_ul, - uint32_t config_idx, - uint32_t root_seq_index, - bool high_speed_flag, - uint32_t zero_corr_zone_config) -{ + uint32_t N_ifft_ul, + uint32_t config_idx, + uint32_t root_seq_index, + bool high_speed_flag, + uint32_t zero_corr_zone_config) { int ret = SRSLTE_ERROR; - if(p != NULL && - N_ifft_ul < 2049 && - config_idx < 64 && - root_seq_index < MAX_ROOTS) - { + if (p != NULL && + N_ifft_ul < 2049 && + config_idx < 64 && + root_seq_index < MAX_ROOTS) { if (N_ifft_ul > p->max_N_ifft_ul) { fprintf(stderr, "PRACH: Error in set_cell(): N_ifft_ul must be lower or equal max_N_ifft_ul in init()\n"); return -1; @@ -432,7 +425,7 @@ int srslte_prach_set_cell(srslte_prach_t *p, // Determine N_zc and N_cs - if(4 == preamble_format){ + if (4 == preamble_format) { if (p->zczc < 7) { p->N_zc = 139; p->N_cs = prach_Ncs_format4[p->zczc]; @@ -440,16 +433,16 @@ int srslte_prach_set_cell(srslte_prach_t *p, fprintf(stderr, "Invalid zeroCorrelationZoneConfig=%d for format4\n", p->zczc); return SRSLTE_ERROR; } - }else{ + } else { p->N_zc = MAX_N_zc; - if(p->hs){ + if (p->hs) { if (p->zczc < 15) { p->N_cs = prach_Ncs_restricted[p->zczc]; } else { fprintf(stderr, "Invalid zeroCorrelationZoneConfig=%d for restricted set\n", p->zczc); return SRSLTE_ERROR; } - }else{ + } else { if (p->zczc < 16) { p->N_cs = prach_Ncs_unrestricted[p->zczc]; } else { @@ -461,10 +454,10 @@ int srslte_prach_set_cell(srslte_prach_t *p, // Set up ZC FFTS if (p->N_zc != MAX_N_zc) { - if(srslte_dft_replan(&p->zc_fft, p->N_zc)){ + if (srslte_dft_replan(&p->zc_fft, p->N_zc)) { return SRSLTE_ERROR; } - if(srslte_dft_replan(&p->zc_ifft, p->N_zc)){ + if (srslte_dft_replan(&p->zc_ifft, p->N_zc)) { return SRSLTE_ERROR; } } @@ -474,16 +467,16 @@ int srslte_prach_set_cell(srslte_prach_t *p, srslte_prach_gen_seqs(p); // Generate sequence FFTs - for(int i=0;izc_fft, p->seqs[i], p->dft_seqs[i]); } // Create our FFT objects and buffers p->N_ifft_ul = N_ifft_ul; - if(4 == preamble_format){ - p->N_ifft_prach = p->N_ifft_ul * DELTA_F/DELTA_F_RA_4; - }else{ - p->N_ifft_prach = p->N_ifft_ul * DELTA_F/DELTA_F_RA; + if (4 == preamble_format) { + p->N_ifft_prach = p->N_ifft_ul * DELTA_F / DELTA_F_RA_4; + } else { + p->N_ifft_prach = p->N_ifft_ul * DELTA_F / DELTA_F_RA; } /* The deadzone specifies the number of samples at the end of the correlation window @@ -496,19 +489,19 @@ int srslte_prach_set_cell(srslte_prach_t *p, p->deadzone = (uint32_t) ceil((float) samp_rate/((float) p->N_zc*subcarrier_spacing)); }*/ - if(srslte_dft_replan(&p->ifft, p->N_ifft_prach)) { + if (srslte_dft_replan(&p->ifft, p->N_ifft_prach)) { fprintf(stderr, "Error creating DFT plan\n"); return -1; } - if(srslte_dft_replan(&p->fft, p->N_ifft_prach)){ + if (srslte_dft_replan(&p->fft, p->N_ifft_prach)) { fprintf(stderr, "Error creating DFT plan\n"); return -1; } - p->N_seq = prach_Tseq[p->f]*p->N_ifft_ul/2048; - p->N_cp = prach_Tcp[p->f]*p->N_ifft_ul/2048; - p->T_seq = prach_Tseq[p->f]*SRSLTE_LTE_TS; - p->T_tot = (prach_Tseq[p->f]+prach_Tcp[p->f])*SRSLTE_LTE_TS; + p->N_seq = prach_Tseq[p->f] * p->N_ifft_ul / 2048; + p->N_cp = prach_Tcp[p->f] * p->N_ifft_ul / 2048; + p->T_seq = prach_Tseq[p->f] * SRSLTE_LTE_TS; + p->T_tot = (prach_Tseq[p->f] + prach_Tcp[p->f]) * SRSLTE_LTE_TS; ret = SRSLTE_SUCCESS; } else { @@ -519,44 +512,42 @@ int srslte_prach_set_cell(srslte_prach_t *p, } int srslte_prach_gen(srslte_prach_t *p, - uint32_t seq_index, - uint32_t freq_offset, - cf_t *signal) -{ + uint32_t seq_index, + uint32_t freq_offset, + cf_t *signal) { int ret = SRSLTE_ERROR; - if(p != NULL && - seq_index < N_SEQS && - signal != NULL) - { + if (p != NULL && + seq_index < N_SEQS && + signal != NULL) { // Calculate parameters uint32_t N_rb_ul = srslte_nof_prb(p->N_ifft_ul); - uint32_t k_0 = freq_offset*N_RB_SC - N_rb_ul*N_RB_SC/2 + p->N_ifft_ul/2; - uint32_t K = DELTA_F/DELTA_F_RA; - uint32_t begin = PHI + (K*k_0) + (K/2); + uint32_t k_0 = freq_offset * N_RB_SC - N_rb_ul * N_RB_SC / 2 + p->N_ifft_ul / 2; + uint32_t K = DELTA_F / DELTA_F_RA; + uint32_t begin = PHI + (K * k_0) + (K / 2); if (6 + freq_offset > N_rb_ul) { fprintf(stderr, "Error no space for PRACH: frequency offset=%d, N_rb_ul=%d\n", freq_offset, N_rb_ul); - return ret; + return ret; } - - DEBUG("N_zc: %d, N_cp: %d, N_seq: %d, N_ifft_prach=%d begin: %d\n", + + DEBUG("N_zc: %d, N_cp: %d, N_seq: %d, N_ifft_prach=%d begin: %d\n", p->N_zc, p->N_cp, p->N_seq, p->N_ifft_prach, begin); - + // Map dft-precoded sequence to ifft bins - memset(p->ifft_in, 0, begin*sizeof(cf_t)); + memset(p->ifft_in, 0, begin * sizeof(cf_t)); memcpy(&p->ifft_in[begin], p->dft_seqs[seq_index], p->N_zc * sizeof(cf_t)); - memset(&p->ifft_in[begin+p->N_zc], 0, (p->N_ifft_prach - begin - p->N_zc) * sizeof(cf_t)); + memset(&p->ifft_in[begin + p->N_zc], 0, (p->N_ifft_prach - begin - p->N_zc) * sizeof(cf_t)); srslte_dft_run(&p->ifft, p->ifft_in, p->ifft_out); // Copy CP into buffer - memcpy(signal, &p->ifft_out[p->N_ifft_prach-p->N_cp], p->N_cp*sizeof(cf_t)); + memcpy(signal, &p->ifft_out[p->N_ifft_prach - p->N_cp], p->N_cp * sizeof(cf_t)); // Copy preamble sequence into buffer - for(int i=0;iN_seq;i++){ - signal[p->N_cp+i] = p->ifft_out[i%p->N_ifft_prach]; + for (int i = 0; i < p->N_seq; i++) { + signal[p->N_cp + i] = p->ifft_out[i % p->N_ifft_prach]; } - + ret = SRSLTE_SUCCESS; } @@ -564,7 +555,7 @@ int srslte_prach_gen(srslte_prach_t *p, } void srslte_prach_set_detect_factor(srslte_prach_t *p, float ratio) { - p->detect_factor = ratio; + p->detect_factor = ratio; } int srslte_prach_detect(srslte_prach_t *p, @@ -572,8 +563,7 @@ int srslte_prach_detect(srslte_prach_t *p, cf_t *signal, uint32_t sig_len, uint32_t *indices, - uint32_t *n_indices) -{ + uint32_t *n_indices) { return srslte_prach_detect_offset(p, freq_offset, signal, sig_len, indices, NULL, NULL, n_indices); } @@ -583,21 +573,19 @@ int srslte_prach_detect_offset(srslte_prach_t *p, uint32_t sig_len, uint32_t *indices, float *t_offsets, - float *peak_to_avg, - uint32_t *n_indices) -{ + float *peak_to_avg, + uint32_t *n_indices) { int ret = SRSLTE_ERROR; - if(p != NULL && - signal != NULL && - sig_len > 0 && - indices != NULL) - { - - if(sig_len < p->N_ifft_prach){ + if (p != NULL && + signal != NULL && + sig_len > 0 && + indices != NULL) { + + if (sig_len < p->N_ifft_prach) { fprintf(stderr, "srslte_prach_detect: Signal length is %d and should be %d\n", sig_len, p->N_ifft_prach); return SRSLTE_ERROR_INVALID_INPUTS; } - + // FFT incoming signal srslte_dft_run(&p->fft, signal, p->signal_fft); @@ -605,66 +593,65 @@ int srslte_prach_detect_offset(srslte_prach_t *p, // Extract bins of interest uint32_t N_rb_ul = srslte_nof_prb(p->N_ifft_ul); - uint32_t k_0 = freq_offset*N_RB_SC - N_rb_ul*N_RB_SC/2 + p->N_ifft_ul/2; - uint32_t K = DELTA_F/DELTA_F_RA; - uint32_t begin = PHI + (K*k_0) + (K/2); + uint32_t k_0 = freq_offset * N_RB_SC - N_rb_ul * N_RB_SC / 2 + p->N_ifft_ul / 2; + uint32_t K = DELTA_F / DELTA_F_RA; + uint32_t begin = PHI + (K * k_0) + (K / 2); - memcpy(p->prach_bins, &p->signal_fft[begin], p->N_zc*sizeof(cf_t)); - - for(int i=0;iN_roots;i++){ + memcpy(p->prach_bins, &p->signal_fft[begin], p->N_zc * sizeof(cf_t)); + + for (int i = 0; i < p->N_roots; i++) { cf_t *root_spec = p->dft_seqs[p->root_seqs_idx[i]]; - + srslte_vec_prod_conj_ccc(p->prach_bins, root_spec, p->corr_spec, p->N_zc); srslte_dft_run(&p->zc_ifft, p->corr_spec, p->corr_spec); - + srslte_vec_abs_square_cf(p->corr_spec, p->corr, p->N_zc); - float corr_ave = srslte_vec_acc_ff(p->corr, p->N_zc)/p->N_zc; - + float corr_ave = srslte_vec_acc_ff(p->corr, p->N_zc) / p->N_zc; + uint32_t winsize = 0; - if(p->N_cs != 0){ + if (p->N_cs != 0) { winsize = p->N_cs; - }else{ + } else { winsize = p->N_zc; } - uint32_t n_wins = p->N_zc/winsize; - - float max_peak = 0; - for(int j=0;jN_zc-(j*p->N_cs))%p->N_zc; - uint32_t end = start+winsize; - if (end>p->deadzone) { - end-=p->deadzone; + uint32_t n_wins = p->N_zc / winsize; + + float max_peak = 0; + for (int j = 0; j < n_wins; j++) { + uint32_t start = (p->N_zc - (j * p->N_cs)) % p->N_zc; + uint32_t end = start + winsize; + if (end > p->deadzone) { + end -= p->deadzone; } start += p->deadzone; p->peak_values[j] = 0; - for(int k=start;kcorr[k] > p->peak_values[j]) { - p->peak_values[j] = p->corr[k]; - p->peak_offsets[j] = k-start; + for (int k = start; k < end; k++) { + if (p->corr[k] > p->peak_values[j]) { + p->peak_values[j] = p->corr[k]; + p->peak_offsets[j] = k - start; if (p->peak_values[j] > max_peak) { max_peak = p->peak_values[j]; } } } } - if (max_peak > p->detect_factor*corr_ave) { - for (int j=0;jpeak_values[j] > p->detect_factor*corr_ave) - { + if (max_peak > p->detect_factor * corr_ave) { + for (int j = 0; j < n_wins; j++) { + if (p->peak_values[j] > p->detect_factor * corr_ave) { //printf("saving prach correlation\n"); //memcpy(save_corr, p->corr, p->N_zc*sizeof(float)); if (indices) { - indices[*n_indices] = (i*n_wins)+j; + indices[*n_indices] = (i * n_wins) + j; } if (peak_to_avg) { - peak_to_avg[*n_indices] = p->peak_values[j]/corr_ave; + peak_to_avg[*n_indices] = p->peak_values[j] / corr_ave; } if (t_offsets) { - t_offsets[*n_indices] = (float) p->peak_offsets[j]*p->T_seq/p->N_zc; - } - (*n_indices)++; + t_offsets[*n_indices] = (float) p->peak_offsets[j] * p->T_seq / p->N_zc; + } + (*n_indices)++; } } } @@ -687,41 +674,37 @@ int srslte_prach_free(srslte_prach_t *p) { srslte_dft_plan_free(&p->zc_ifft); if (p->signal_fft) { - free(p->signal_fft); + free(p->signal_fft); } - + bzero(p, sizeof(srslte_prach_t)); return 0; } -int srslte_prach_print_seqs(srslte_prach_t *p) -{ - for(int i=0; iseqs[i] , sizeof(cf_t), p->N_zc, f); + fwrite(p->seqs[i], sizeof(cf_t), p->N_zc, f); fclose(f); } - for(int i=0; idft_seqs[i] , sizeof(cf_t), p->N_zc, f); + fwrite(p->dft_seqs[i], sizeof(cf_t), p->N_zc, f); fclose(f); } - for(int i=0;iN_roots;i++) - { + for (int i = 0; i < p->N_roots; i++) { FILE *f; char str[32]; sprintf(str, "prach_root_seq_%d.bin", i); f = fopen(str, "wb"); - fwrite(p->seqs[p->root_seqs_idx[i]] , sizeof(cf_t), p->N_zc, f); + fwrite(p->seqs[p->root_seqs_idx[i]], sizeof(cf_t), p->N_zc, f); fclose(f); } return 0; From 3982db00fe93af3bc35c01079197b81e18437cc1 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 18:07:39 +0100 Subject: [PATCH 052/342] Removed printf --- lib/src/phy/phch/prach.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/src/phy/phch/prach.c b/lib/src/phy/phch/prach.c index 74356417a..f6d9b31d9 100644 --- a/lib/src/phy/phch/prach.c +++ b/lib/src/phy/phch/prach.c @@ -316,9 +316,6 @@ int srslte_prach_gen_seqs(srslte_prach_t *p) { } else { C_v = v * p->N_cs; } - if (i == 46) { - printf("i=%d, C_v=%d\n", i, C_v); - } for (int j = 0; j < p->N_zc; j++) { p->seqs[i][j] = root[(j + C_v) % p->N_zc]; } From ea07f695adc2d7e4c3d8c46500ddf63a9e4dfb9f Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 18:07:39 +0100 Subject: [PATCH 053/342] Removed printf --- lib/src/phy/phch/prach.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/src/phy/phch/prach.c b/lib/src/phy/phch/prach.c index 74356417a..f6d9b31d9 100644 --- a/lib/src/phy/phch/prach.c +++ b/lib/src/phy/phch/prach.c @@ -316,9 +316,6 @@ int srslte_prach_gen_seqs(srslte_prach_t *p) { } else { C_v = v * p->N_cs; } - if (i == 46) { - printf("i=%d, C_v=%d\n", i, C_v); - } for (int j = 0; j < p->N_zc; j++) { p->seqs[i][j] = root[(j + C_v) % p->N_zc]; } From 230364a6046bd3b2fbc1d8d88442e2fa4df560a3 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 00:05:52 +0100 Subject: [PATCH 054/342] Defaut in-sync for neighbour cell to true --- srsue/hdr/upper/rrc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 4ac2dfa2f..1aaf6f29b 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -87,7 +87,7 @@ class cell_t this->phy_cell = phy_cell; this->rsrp = rsrp; this->earfcn = earfcn; - in_sync = false; + in_sync = true; bzero(&sib1, sizeof(sib1)); bzero(&sib2, sizeof(sib2)); bzero(&sib3, sizeof(sib3)); From c78a6e4c0ddb5189b17c08a18591f4ac9450c826 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 00:47:08 +0100 Subject: [PATCH 055/342] Changed SSS algorithm --- lib/src/phy/sync/sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/sync/sync.c b/lib/src/phy/sync/sync.c index a49311fea..c948a53d4 100644 --- a/lib/src/phy/sync/sync.c +++ b/lib/src/phy/sync/sync.c @@ -71,7 +71,7 @@ int srslte_sync_init_decim(srslte_sync_t *q, uint32_t frame_size, uint32_t max_o q->N_id_1 = 1000; q->cfo_ema_alpha = CFO_EMA_ALPHA; - q->sss_alg = SSS_PARTIAL_3; + q->sss_alg = SSS_FULL; q->detect_cp = true; q->sss_en = true; From fd1e22a7103a04e2b2be4d2873d658e6d49a224d Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 00:47:22 +0100 Subject: [PATCH 056/342] Fixed Measure neighbour exiting too early --- srsue/src/phy/phch_recv.cc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index c46316af9..c8f804031 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1169,6 +1169,9 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in return ret; } } + if (ret != ERROR) { + return MEASURE_OK; + } } else { Info("INTRA: not running because offset=%d, sf_len*max_sf=%d*%d\n", offset, sf_len, max_sf); } @@ -1261,13 +1264,11 @@ void phch_recv::scell_recv::init(srslte::log *log_h, bool sic_pss_enabled, uint3 srslte_sync_set_cfo_i_enable(&sync_find, false); srslte_sync_set_cfo_pss_enable(&sync_find, true); srslte_sync_set_pss_filt_enable(&sync_find, true); - srslte_sync_set_sss_eq_enable(&sync_find, false); + srslte_sync_set_sss_eq_enable(&sync_find, true); sync_find.pss.chest_on_filter = true; - if (!sic_pss_enabled) { - sync_find.sss_channel_equalize = false; - } + sync_find.sss_channel_equalize = true; reset(); } @@ -1308,13 +1309,12 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset, if (n_id_2 != (cell.id%3) || sic_pss_enabled) { srslte_sync_set_N_id_2(&sync_find, n_id_2); - srslte_sync_find_ret_t sync_res, best_sync_res; + srslte_sync_find_ret_t sync_res; do { srslte_sync_reset(&sync_find); srslte_sync_cfo_reset(&sync_find); - best_sync_res = SRSLTE_SYNC_NOFOUND; sync_res = SRSLTE_SYNC_NOFOUND; cell_id = 0; float max_peak = -1; @@ -1327,14 +1327,13 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset, n_id_2, sf5_cnt, nof_sf/5, sync_res, srslte_sync_get_sf_idx(&sync_find), peak_idx, sync_find.peak_value); if (sync_find.peak_value > max_peak && sync_res == SRSLTE_SYNC_FOUND) { - best_sync_res = sync_res; max_sf5 = sf5_cnt; max_sf_idx = srslte_sync_get_sf_idx(&sync_find); cell_id = srslte_sync_get_cell_id(&sync_find); } } - switch(best_sync_res) { + switch(sync_res) { case SRSLTE_SYNC_ERROR: return SRSLTE_ERROR; fprintf(stderr, "Error finding correlation peak\n"); From 70dfa3b2a971785995a52157d05e99e63c81ade4 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 15:06:22 +0100 Subject: [PATCH 057/342] Fixes #6 AGC --- lib/include/srslte/phy/agc/agc.h | 4 ++-- lib/src/phy/agc/agc.c | 2 +- lib/src/phy/ue/ue_sync.c | 14 +++----------- srsue/hdr/phy/phch_recv.h | 1 + srsue/src/phy/phch_recv.cc | 24 ++++++++++++++++++------ srsue/src/phy/phch_worker.cc | 2 +- srsue/src/ue.cc | 11 ++++++----- srsue/src/upper/rrc.cc | 1 + 8 files changed, 33 insertions(+), 26 deletions(-) diff --git a/lib/include/srslte/phy/agc/agc.h b/lib/include/srslte/phy/agc/agc.h index 941983806..0a6bba8c1 100644 --- a/lib/include/srslte/phy/agc/agc.h +++ b/lib/include/srslte/phy/agc/agc.h @@ -42,8 +42,8 @@ #include "srslte/config.h" -#define SRSLTE_AGC_DEFAULT_TARGET 0.7 -#define SRSLTE_AGC_DEFAULT_BW (5e-1) +#define SRSLTE_AGC_DEFAULT_TARGET 0.3 +#define SRSLTE_AGC_DEFAULT_BW 0.7 typedef enum SRSLTE_API { SRSLTE_AGC_MODE_ENERGY = 0, diff --git a/lib/src/phy/agc/agc.c b/lib/src/phy/agc/agc.c index 42a6ef09d..ef09307c1 100644 --- a/lib/src/phy/agc/agc.c +++ b/lib/src/phy/agc/agc.c @@ -177,7 +177,7 @@ void srslte_agc_process(srslte_agc_t *q, cf_t *signal, uint32_t len) { gg = expf(-0.5*q->bandwidth*logf(q->y_out/q->target)); q->gain *= gg; } - DEBUG("AGC gain: %.2f (%.2f) y_out=%.3f, y=%.3f target=%.1f gg=%.2f\n", gain_db, gain_uhd_db, q->y_out, y, q->target, gg); + INFO("AGC gain: %.2f (%.2f) y_out=%.3f, y=%.3f target=%.1f gg=%.2f\n", gain_db, gain_uhd_db, q->y_out, y, q->target, gg); } } } diff --git a/lib/src/phy/ue/ue_sync.c b/lib/src/phy/ue/ue_sync.c index 7ee97c21b..d99bff89a 100644 --- a/lib/src/phy/ue/ue_sync.c +++ b/lib/src/phy/ue/ue_sync.c @@ -144,18 +144,11 @@ void srslte_ue_sync_reset(srslte_ue_sync_t *q) { int srslte_ue_sync_start_agc(srslte_ue_sync_t *q, double (set_gain_callback)(void*, double), float init_gain_value) { - uint32_t nframes; - if (q->nof_recv_sf == 1) { - nframes = 10; - } else { - nframes = 0; - } - int n = srslte_agc_init_uhd(&q->agc, SRSLTE_AGC_MODE_PEAK_AMPLITUDE, nframes, set_gain_callback, q->stream); + int n = srslte_agc_init_uhd(&q->agc, SRSLTE_AGC_MODE_PEAK_AMPLITUDE, 0, set_gain_callback, q->stream); q->do_agc = n==0?true:false; if (q->do_agc) { srslte_agc_set_gain(&q->agc, init_gain_value); - srslte_agc_set_target(&q->agc, 0.3); - srslte_agc_set_bandwidth(&q->agc, 0.8); + srslte_ue_sync_set_agc_period(q, 4); } return n; } @@ -329,7 +322,6 @@ int srslte_ue_sync_set_cell(srslte_ue_sync_t *q, srslte_cell_t cell) memcpy(&q->cell, &cell, sizeof(srslte_cell_t)); q->fft_size = srslte_symbol_sz(q->cell.nof_prb); q->sf_len = SRSLTE_SF_LEN(q->fft_size); - q->agc_period = 0; if (cell.id == 1000) { @@ -789,7 +781,7 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE if (q->do_agc && (q->agc_period == 0 || (q->agc_period && (q->frame_total_cnt%q->agc_period) == 0))) { - srslte_agc_process(&q->agc, input_buffer[0], q->sf_len); + srslte_agc_process(&q->agc, input_buffer[0], q->sf_len); } /* Track PSS/SSS around the expected PSS position diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index efe46d63e..66c3342fb 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -125,6 +125,7 @@ private: float get_last_gain(); float get_last_cfo(); void set_N_id_2(int N_id_2); + void set_agc_enable(bool enable); ret_code run(srslte_cell_t *cell); private: diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index c8f804031..bf09f5f34 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -174,6 +174,16 @@ bool phch_recv::wait_radio_reset() { void phch_recv::set_agc_enable(bool enable) { do_agc = enable; + if (do_agc) { + if (running && radio_h) { + srslte_ue_sync_start_agc(&ue_sync, callback_set_rx_gain, radio_h->get_rx_gain()); + search_p.set_agc_enable(true); + } else { + fprintf(stderr, "Error setting AGC: PHY not initiatec\n"); + } + } else { + fprintf(stderr, "Error stopping AGC: not implemented\n"); + } } void phch_recv::set_time_adv_sec(float _time_adv_sec) @@ -832,6 +842,14 @@ float phch_recv::search::get_last_cfo() return srslte_ue_sync_get_cfo(&ue_mib_sync.ue_sync); } +void phch_recv::search::set_agc_enable(bool enable) { + if (enable) { + srslte_ue_sync_start_agc(&ue_mib_sync.ue_sync, callback_set_rx_gain, p->radio_h->get_rx_gain()); + } else { + fprintf(stderr, "Error stop AGC not implemented\n"); + } +} + phch_recv::search::ret_code phch_recv::search::run(srslte_cell_t *cell) { @@ -891,11 +909,6 @@ phch_recv::search::ret_code phch_recv::search::run(srslte_cell_t *cell) // Set options defined in expert section p->set_ue_sync_opts(&ue_mib_sync.ue_sync, cfo); - // Start AGC after initial cell search - if (p->do_agc) { - srslte_ue_sync_start_agc(&ue_mib_sync.ue_sync, callback_set_rx_gain, p->radio_h->get_rx_gain()); - } - srslte_ue_sync_reset(&ue_mib_sync.ue_sync); /* Find and decode MIB */ @@ -1011,7 +1024,6 @@ phch_recv::sfn_sync::ret_code phch_recv::sfn_sync::run_subframe(srslte_cell_t *c Info("SYNC: DONE, TTI=%d, sfn_offset=%d\n", *tti_cnt, sfn_offset); } - srslte_ue_sync_set_agc_period(ue_sync, 20); srslte_ue_sync_decode_sss_on_track(ue_sync, true); reset(); return SFN_FOUND; diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index f7e1381f8..a4e6eeb47 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -1436,7 +1436,7 @@ void phch_worker::update_measurements() dl_metrics.rsrp = phy->avg_rsrp_dbm; dl_metrics.rsrq = phy->avg_rsrq_db; dl_metrics.rssi = phy->avg_rssi_dbm; - dl_metrics.pathloss = phy->pathloss; + dl_metrics.pathloss = phy->get_radio()->get_rx_gain(); dl_metrics.sinr = phy->avg_snr_db; dl_metrics.turbo_iters = srslte_pdsch_last_noi(&ue_dl.pdsch); phy->set_dl_metrics(dl_metrics); diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index a9277e62c..611bac620 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -130,11 +130,7 @@ bool ue::init(all_args_t *args_) // Init layers - if (args->rf.rx_gain < 0) { - phy.set_agc_enable(true); - } - - // PHY initis in background, start before radio + // PHY inits in background, start before radio args->expert.phy.nof_rx_ant = args->rf.nof_rx_ant; phy.init(&radio, &mac, &rrc, phy_log, &args->expert.phy); @@ -222,6 +218,11 @@ bool ue::init(all_args_t *args_) phy.wait_initialize(); phy.configure_ul_params(); + // Enable AGC once PHY is initialized + if (args->rf.rx_gain < 0) { + phy.set_agc_enable(true); + } + printf("...\n"); nas.attach_request(); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index f2e410e5d..f93401fc5 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1062,6 +1062,7 @@ bool rrc::ho_prepare() { int target_cell_idx = find_neighbour_cell(serving_cell->earfcn, mob_reconf.mob_ctrl_info.target_pci); if (target_cell_idx < 0) { + rrc_log->console("Received HO command to unknown PCI=%d\n", mob_reconf.mob_ctrl_info.target_pci); rrc_log->error("Could not find target cell earfcn=%d, pci=%d\n", serving_cell->earfcn, mob_reconf.mob_ctrl_info.target_pci); return false; } From 411711951079a8165f5a7cfe8c4fcd8492258f7f Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 18:17:15 +0100 Subject: [PATCH 058/342] Correct a possible sign overflow --- lib/src/phy/phch/prach.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/src/phy/phch/prach.c b/lib/src/phy/phch/prach.c index f6d9b31d9..b5d51ba0b 100644 --- a/lib/src/phy/phch/prach.c +++ b/lib/src/phy/phch/prach.c @@ -282,9 +282,11 @@ int srslte_prach_gen_seqs(srslte_prach_t *p) { N_shift = (p->N_zc - 2 * d_u) / p->N_cs; d_start = p->N_zc - 2 * d_u + N_shift * p->N_cs; N_group = d_u / d_start; - N_neg_shift = (d_u - N_group * d_start) / p->N_cs; - if (N_neg_shift < 0) + if (d_u > N_group * d_start) { + N_neg_shift = (d_u - N_group * d_start) / p->N_cs; + } else { N_neg_shift = 0; + } if (N_neg_shift > N_shift) N_neg_shift = N_shift; } else { From 26f782d8a48291f4d99d55f0872209fe280d44f0 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 13 Feb 2018 17:45:25 +0000 Subject: [PATCH 059/342] Starting to integrity check all Uplink NAS Transport messages. --- srsepc/src/mme/s1ap.cc | 4 +- srsepc/src/mme/s1ap_nas_transport.cc | 103 ++++++++++++++++++++++----- 2 files changed, 86 insertions(+), 21 deletions(-) diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 4cd6f421c..31db87cf5 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -74,7 +74,7 @@ s1ap::init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log) m_s1ap_args = s1ap_args; srslte::s1ap_mccmnc_to_plmn(s1ap_args.mcc, s1ap_args.mnc, &m_plmn); - m_next_m_tmsi = rand(); + m_next_m_tmsi = 0xF000; //Init log m_s1ap_log = s1ap_log; @@ -517,7 +517,7 @@ s1ap::allocate_m_tmsi(uint64_t imsi) { uint32_t m_tmsi = m_next_m_tmsi++; m_tmsi_to_imsi.insert(std::pair(m_tmsi,imsi)); - m_s1ap_log->info("Allocated M-TMSI %d,\n"); + m_s1ap_log->info("Allocated M-TMSI 0x%x,\n",m_tmsi); //uint32_t m_tmsi = 0x0123; return m_tmsi; } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index bd4865d03..2b07eab24 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -117,37 +117,101 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA bool s1ap_nas_transport::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) { - - bool ue_valid = true; + uint8_t pd, msg_type, sec_hdr_type; uint32_t enb_ue_s1ap_id = ul_xport->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID; uint32_t mme_ue_s1ap_id = ul_xport->MME_UE_S1AP_ID.MME_UE_S1AP_ID; + ue_emm_ctx_t *ue_emm_ctx = NULL; + bool mac_valid = false; + //Get UE ECM context ue_ecm_ctx_t *ue_ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); if(ue_ecm_ctx == NULL) { m_s1ap_log->warning("Received uplink NAS, but could not find UE ECM context. MME-UE S1AP id: %lu\n",mme_ue_s1ap_id); return false; } - m_s1ap_log->debug("Received uplink NAS and found UE. MME-UE S1AP id: %lu\n",mme_ue_s1ap_id); - //Get NAS message type - uint8_t pd, msg_type; - srslte::byte_buffer_t *nas_msg = m_pool->allocate(); + m_s1ap_log->debug("Received uplink NAS and found UE ECM context. MME-UE S1AP id: %lu\n",mme_ue_s1ap_id); + //Parse NAS message header + srslte::byte_buffer_t *nas_msg = m_pool->allocate(); memcpy(nas_msg->msg, &ul_xport->NAS_PDU.buffer, ul_xport->NAS_PDU.n_octets); nas_msg->N_bytes = ul_xport->NAS_PDU.n_octets; liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &pd, &msg_type); - switch (msg_type) { + // Parse the message security header + liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &pd, &sec_hdr_type); + + //Find UE EMM context if message is security protected. + if(sec_hdr_type != LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS) + { + //Get EMM context to do integrity check/de-chiphering + ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); + if(ue_emm_ctx == NULL) + { + m_s1ap_log->warning("Uplink NAS: could not find security context for integrity protected message. MME-UE S1AP id: %lu\n",mme_ue_s1ap_id); + m_pool->deallocate(nas_msg); + return false; + } + } + + if(sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS) + { + //Plain NAS, only identity response is valid. + switch(msg_type) + { + case LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE: + m_s1ap_log->info("Uplink NAS: Received Identity Response\n"); + m_s1ap_log->console("Uplink NAS: Received Identity Response\n"); + handle_identity_response(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); + break; case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE: m_s1ap_log->info("Uplink NAS: Received Authentication Response\n"); m_s1ap_log->console("Uplink NAS: Received Authentication Response\n"); handle_nas_authentication_response(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); break; - case LIBLTE_MME_MSG_TYPE_SECURITY_MODE_COMPLETE: + default: + m_s1ap_log->warning("Unhandled Plain NAS message 0x%x\n", msg_type ); + m_s1ap_log->console("Unhandled Plain NAS message 0x%x\n", msg_type ); + m_pool->deallocate(nas_msg); + return false; + } + } + else if(sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT || sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT) + { + switch (msg_type) { + case LIBLTE_MME_MSG_TYPE_SECURITY_MODE_COMPLETE: m_s1ap_log->info("Uplink NAS: Received Security Mode Complete\n"); m_s1ap_log->console("Uplink NAS: Received Security Mode Complete\n"); - handle_nas_security_mode_complete(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); + ue_emm_ctx->security_ctxt.ul_nas_count = 0; + ue_emm_ctx->security_ctxt.dl_nas_count = 0; + mac_valid = integrity_check(ue_emm_ctx,nas_msg); + if(mac_valid){ + handle_nas_security_mode_complete(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); + } else { + m_s1ap_log->warning("Invalid MAC in Security Mode Command Complete message.\n" ); + } + break; + default: + m_s1ap_log->warning("Unhandled NAS message with new EPS security context 0x%x\n", msg_type ); + m_s1ap_log->warning("Unhandled NAS message with new EPS security context 0x%x\n", msg_type ); + } + } + else if(sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY || sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED) + { + //Integrity protected NAS message, possibly chiphered. + ue_emm_ctx->security_ctxt.ul_nas_count++; + mac_valid = integrity_check(ue_emm_ctx,nas_msg); + if(!mac_valid && msg_type != LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE){ + m_s1ap_log->warning("Invalid MAC in NAS message type 0x%x.\n", msg_type); + m_pool->deallocate(nas_msg); + return false; + } + switch (msg_type) { + case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE: + m_s1ap_log->info("Uplink NAS: Received Authentication Response\n"); + m_s1ap_log->console("Uplink NAS: Received Authentication Response\n"); + handle_nas_authentication_response(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); break; case LIBLTE_MME_MSG_TYPE_ATTACH_COMPLETE: m_s1ap_log->info("Uplink NAS: Received Attach Complete\n"); @@ -159,11 +223,6 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA m_s1ap_log->console("Uplink NAS: Received ESM Information Response\n"); handle_esm_information_response(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); break; - case LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE: - m_s1ap_log->info("Uplink NAS: Received Identity Response\n"); - m_s1ap_log->console("Uplink NAS: Received Identity Response\n"); - handle_identity_response(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); - break; case LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REQUEST: m_s1ap_log->info("UL NAS: Tracking Area Update Request\n"); handle_tracking_area_update_request(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); @@ -173,8 +232,16 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA m_s1ap_log->console("Unhandled NAS message 0x%x\n", msg_type ); m_pool->deallocate(nas_msg); return false; + } + } + else + { + m_s1ap_log->error("Unhandled security header type in Uplink NAS Transport: %d\n", sec_hdr_type); + m_pool->deallocate(nas_msg); + return false; } + if(*reply_flag == true) { m_s1ap_log->info("DL NAS: Sent Downlink NAS message\n"); @@ -221,11 +288,11 @@ s1ap_nas_transport::handle_nas_attach_request(uint32_t enb_ue_s1ap_id, { m_s1ap_log->console("Attach Request -- IMSI-style attach request\n"); m_s1ap_log->info("Attach Request -- IMSI-style attach request\n"); - if(sec_hdr_type != LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS) + /*if(sec_hdr_type != LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS) { m_s1ap_log->error("Attach request -- IMSI-stlye attach request is not plain NAS\n"); return false; - } + }*/ handle_nas_imsi_attach_request(enb_ue_s1ap_id, attach_req, pdn_con_req, reply_buffer, reply_flag, enb_sri); } else if(attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI) @@ -548,8 +615,6 @@ s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas return false; } - //TODO Check integrity - //TODO Handle imeisv if(sm_comp.imeisv_present) { @@ -858,7 +923,7 @@ s1ap_nas_transport::pack_authentication_reject(srslte::byte_buffer_t *reply_msg, if(err != LIBLTE_SUCCESS) { m_s1ap_log->error("Error packing Athentication Reject\n"); - m_s1ap_log->console("Error packing Athentication Reject\n"); + m_s1ap_log->console("Error packing Athentication Reject\n"); return false; } From 28d5130320137cc4fa6a5aa2b26aea08ae223285 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 13 Feb 2018 18:29:21 +0000 Subject: [PATCH 060/342] Incrementing DL NAS count --- srsepc/src/mme/s1ap_nas_transport.cc | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 2b07eab24..1e71a5936 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -176,6 +176,15 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA m_pool->deallocate(nas_msg); return false; } + //Increment UL NAS count. + ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); + if(ue_emm_ctx == NULL) + { + m_s1ap_log->warning("Could not find UE EMM context in ", msg_type ); + m_pool->deallocate(nas_msg); + return false; + } + ue_emm_ctx->security_ctxt.ul_nas_count++; } else if(sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT || sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT) { @@ -244,8 +253,12 @@ 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_emm_ctx != NULL) + { + ue_emm_ctx->security_ctxt.dl_nas_count++; + m_s1ap_log->console("DL NAS: Sent Downlink NAs Message. DL NAS Count=%d\n",ue_emm_ctx->security_ctxt.dl_nas_count); + m_s1ap_log->info("DL NAS: Sent Downlink NAS message. DL NAS Count=%d\n",ue_emm_ctx->security_ctxt.dl_nas_count); + } } m_pool->deallocate(nas_msg); @@ -734,9 +747,9 @@ s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ //Get UE EMM context ue_emm_ctx_t ue_emm_ctx; if(m_s1ap->get_tmp_ue_emm_ctx(ue_ecm_ctx->mme_ue_s1ap_id, &ue_emm_ctx) == false) - { - m_s1ap_log->error("Could not find UE's temporary EMM context. MME UE S1AP Id: %d\n",ue_ecm_ctx->mme_ue_s1ap_id); - return false; + { + m_s1ap_log->error("Could not find UE's temporary EMM context. MME UE S1AP Id: %d\n",ue_ecm_ctx->mme_ue_s1ap_id); + return false; } ue_emm_ctx.imsi=imsi; From fa86862e8a65fd9d7e76c876159c988866ac870d Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 13 Feb 2018 19:40:13 +0000 Subject: [PATCH 061/342] Incrementing DL NAS COUNT and UL NAS COUNT. k_eNB is being generated incorrectly. --- srsepc/src/mme/s1ap_nas_transport.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 1e71a5936..580e66f60 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -255,9 +255,9 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA { if(ue_emm_ctx != NULL) { - ue_emm_ctx->security_ctxt.dl_nas_count++; m_s1ap_log->console("DL NAS: Sent Downlink NAs Message. DL NAS Count=%d\n",ue_emm_ctx->security_ctxt.dl_nas_count); m_s1ap_log->info("DL NAS: Sent Downlink NAS message. DL NAS Count=%d\n",ue_emm_ctx->security_ctxt.dl_nas_count); + //ue_emm_ctx->security_ctxt.dl_nas_count++; } } m_pool->deallocate(nas_msg); @@ -1034,7 +1034,7 @@ s1ap_nas_transport::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, uint8_t sec_hdr_type=3; - ue_emm_ctx->security_ctxt.dl_nas_count = 0; + // ue_emm_ctx->security_ctxt.dl_nas_count = 0; LIBLTE_ERROR_ENUM err = liblte_mme_pack_security_mode_command_msg(&sm_cmd,sec_hdr_type, ue_emm_ctx->security_ctxt.dl_nas_count,(LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); if(err != LIBLTE_SUCCESS) { From e6274801ce70edbee65c51a67b0f92ef0899c6f2 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 22:33:28 +0100 Subject: [PATCH 062/342] Restored pathloss metric --- 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 a4e6eeb47..f7e1381f8 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -1436,7 +1436,7 @@ void phch_worker::update_measurements() dl_metrics.rsrp = phy->avg_rsrp_dbm; dl_metrics.rsrq = phy->avg_rsrq_db; dl_metrics.rssi = phy->avg_rssi_dbm; - dl_metrics.pathloss = phy->get_radio()->get_rx_gain(); + dl_metrics.pathloss = phy->pathloss; dl_metrics.sinr = phy->avg_snr_db; dl_metrics.turbo_iters = srslte_pdsch_last_noi(&ue_dl.pdsch); phy->set_dl_metrics(dl_metrics); From ca4a22aeaf244cca2cdf2003eb8b6a29bc6e1860 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 23:20:35 +0100 Subject: [PATCH 063/342] Transmit Msg3 only if available --- srsue/hdr/mac/ul_harq.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index b98a7497a..644167746 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -237,8 +237,8 @@ private: // New transmission reset(); - // Uplink grant in a RAR - if (grant->is_from_rar) { + // Uplink grant in a RAR and there is a PDU in the Msg3 buffer + if (grant->is_from_rar && !harq_entity->mux_unit->msg3_is_transmitted()) { Debug("Getting Msg3 buffer payload, grant size=%d bytes\n", grant->n_bytes[0]); pdu_ptr = harq_entity->mux_unit->msg3_get(payload_buffer, grant->n_bytes[0]); if (pdu_ptr) { From 13a16e200cd088b7a3ea554a99aa81ff995ccca6 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 23:31:52 +0100 Subject: [PATCH 064/342] Transmit Msg3 only if available (2) --- srsue/hdr/mac/mux.h | 4 ++++ srsue/hdr/mac/ul_harq.h | 3 ++- srsue/src/mac/mux.cc | 13 ++++++++++++- srsue/src/mac/proc_ra.cc | 3 ++- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/srsue/hdr/mac/mux.h b/srsue/hdr/mac/mux.h index ebc61b5c6..889dd68f3 100644 --- a/srsue/hdr/mac/mux.h +++ b/srsue/hdr/mac/mux.h @@ -67,6 +67,9 @@ public: void msg3_flush(); bool msg3_is_transmitted(); + + void msg3_prepare(); + bool msg3_is_pending(); void append_crnti_ce_next_tx(uint16_t crnti); @@ -105,6 +108,7 @@ private: /* PDU Buffer */ srslte::sch_pdu pdu_msg; bool msg3_has_been_transmitted; + bool msg3_pending; }; } // namespace srsue diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index 644167746..21b84aa60 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -238,7 +238,7 @@ private: reset(); // Uplink grant in a RAR and there is a PDU in the Msg3 buffer - if (grant->is_from_rar && !harq_entity->mux_unit->msg3_is_transmitted()) { + if (grant->is_from_rar && harq_entity->mux_unit->msg3_is_pending()) { Debug("Getting Msg3 buffer payload, grant size=%d bytes\n", grant->n_bytes[0]); pdu_ptr = harq_entity->mux_unit->msg3_get(payload_buffer, grant->n_bytes[0]); if (pdu_ptr) { @@ -246,6 +246,7 @@ private: } else { Warning("UL RAR grant available but no Msg3 on buffer\n"); } + printf("Transmitted Msg3\n"); // Normal UL grant } else { diff --git a/srsue/src/mac/mux.cc b/srsue/src/mac/mux.cc index ba2b45209..2f8ade2af 100644 --- a/srsue/src/mac/mux.cc +++ b/srsue/src/mac/mux.cc @@ -65,6 +65,7 @@ void mux::reset() for (uint32_t i=0;imsg3_prepare(); rntis->temp_rnti = rar_pdu_msg.get()->get_temp_crnti(); phy_h->pdcch_dl_search(SRSLTE_RNTI_TEMP, rar_pdu_msg.get()->get_temp_crnti()); From 1db4644c7b5443592d06c5661d7a7defec21f9c3 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 23:46:12 +0100 Subject: [PATCH 065/342] Set PHY crnti before RA done no contention --- srsue/src/mac/proc_ra.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srsue/src/mac/proc_ra.cc b/srsue/src/mac/proc_ra.cc index 3860fd809..b7aa90b26 100644 --- a/srsue/src/mac/proc_ra.cc +++ b/srsue/src/mac/proc_ra.cc @@ -347,7 +347,8 @@ void ra_proc::tb_decoded_ok() { if (preambleIndex > 0) { // Preamble selected by Network - state = COMPLETION; + phy_h->set_crnti(rntis->crnti); + state = COMPLETION; } else { // Preamble selected by UE MAC mux_unit->msg3_prepare(); From d52c2402ff590ffd0d38f1b9fdd53228e04e5af9 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Feb 2018 23:53:08 +0100 Subject: [PATCH 066/342] Revert "Set PHY crnti before RA done no contention" This reverts commit 1db4644c7b5443592d06c5661d7a7defec21f9c3. --- srsue/src/mac/proc_ra.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/srsue/src/mac/proc_ra.cc b/srsue/src/mac/proc_ra.cc index b7aa90b26..3860fd809 100644 --- a/srsue/src/mac/proc_ra.cc +++ b/srsue/src/mac/proc_ra.cc @@ -347,8 +347,7 @@ void ra_proc::tb_decoded_ok() { if (preambleIndex > 0) { // Preamble selected by Network - phy_h->set_crnti(rntis->crnti); - state = COMPLETION; + state = COMPLETION; } else { // Preamble selected by UE MAC mux_unit->msg3_prepare(); From 9acefc53f8477c99231193162ca98b5e53c5b0f2 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Feb 2018 00:00:31 +0100 Subject: [PATCH 067/342] Set C-RNTI when grant from RAR but no Msg3 --- srsue/hdr/mac/ul_harq.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index 21b84aa60..4ea37cb07 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -250,6 +250,9 @@ private: // Normal UL grant } else { + if (grant->is_from_rar) { + grant->rnti = harq_entity->rntis->crnti; + } // Request a MAC PDU from the Multiplexing & Assemble Unit pdu_ptr = harq_entity->mux_unit->pdu_get(payload_buffer, grant->n_bytes[0], tti_tx, pid); if (pdu_ptr) { From 898c86d95490c9e938ace88dc2a92557d5c8af14 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 13 Feb 2018 23:28:09 +0100 Subject: [PATCH 068/342] Channel estimattor selects the strongest RSRP. --- lib/src/phy/ch_estimation/chest_dl.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index 3dae7f9e5..ba9ae40e6 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -691,14 +691,22 @@ float srslte_chest_dl_get_rsrp_ant_port(srslte_chest_dl_t *q, uint32_t ant_idx, } float srslte_chest_dl_get_rsrp_port(srslte_chest_dl_t *q, uint32_t port) { - float n = 0; + float max = -INFINITY; for (int i = 0; i < q->last_nof_antennas; i++) { - n += q->rsrp[i][port]; + if (q->rsrp[i][port] > max) { + max = q->rsrp[i][port]; + } } - return n / q->last_nof_antennas; + return max; } float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) { - // Note: use only port 0 but average across antennas - return srslte_chest_dl_get_rsrp_port(q, 0); + float max = -INFINITY; + for (int i = 0; i < q->cell.nof_ports; ++i) { + float v = srslte_chest_dl_get_rsrp_port(q, i); + if (max < v) { + max = v; + } + } + return max; } From aedcfbb686340144b437684c9c8e7337407d13f2 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 14 Feb 2018 10:48:44 +0000 Subject: [PATCH 069/342] Added print of UL NAS Count --- srsepc/src/mme/s1ap_nas_transport.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 580e66f60..eaf01bd84 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -255,8 +255,8 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA { if(ue_emm_ctx != NULL) { - m_s1ap_log->console("DL NAS: Sent Downlink NAs Message. DL NAS Count=%d\n",ue_emm_ctx->security_ctxt.dl_nas_count); - m_s1ap_log->info("DL NAS: Sent Downlink NAS message. DL NAS Count=%d\n",ue_emm_ctx->security_ctxt.dl_nas_count); + m_s1ap_log->console("DL NAS: Sent Downlink NAs Message. DL NAS Count=%d, UL NAS count=%d\n",ue_emm_ctx->security_ctxt.dl_nas_count,ue_emm_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_emm_ctx->security_ctxt.dl_nas_count, ue_emm_ctx->security_ctxt.ul_nas_count); //ue_emm_ctx->security_ctxt.dl_nas_count++; } } From 012f026543e59730fbb323bdda7cef38942478c3 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 14 Feb 2018 10:59:54 +0000 Subject: [PATCH 070/342] 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); From 1c4dce80660bbd1b048500b4669d2243945c5791 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 14 Feb 2018 12:28:55 +0000 Subject: [PATCH 071/342] Generating k_enb in the securty mode command. Fixed wrong k_enb generation. Integrity is being checked corretly in upstream NAS messages. --- srsepc/hdr/mme/s1ap_common.h | 1 + srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 7 +++---- srsepc/src/mme/s1ap_nas_transport.cc | 17 +++++++++++++---- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index 84ced0637..8bb6944ff 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -115,6 +115,7 @@ typedef struct{ srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo; uint8_t k_nas_enc[32]; uint8_t k_nas_int[32]; + uint8_t k_enb[32]; LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT ue_network_cap; bool ms_network_cap_present; LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT ms_network_cap; diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 3fce06de6..b2654cedd 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -167,10 +167,9 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, } // in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer[0] = 1; //EIA1 } - uint8_t key_enb[32]; - liblte_security_generate_k_enb(ue_emm_ctx->security_ctxt.k_asme, ue_emm_ctx->security_ctxt.ul_nas_count, key_enb); - liblte_unpack(key_enb, 32, in_ctxt_req->SecurityKey.buffer); - m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",ue_emm_ctx->security_ctxt.ul_nas_count); + //Get K eNB + liblte_unpack(ue_emm_ctx->security_ctxt.k_enb, 32, in_ctxt_req->SecurityKey.buffer); + m_s1ap_log->info_hex(ue_emm_ctx->security_ctxt.k_enb, 32, "Initial Context Setup Request -- Key eNB\n"); //Set Attach accepted and activat default bearer NAS messages if(cs_resp->paa_present != true) { diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index eaf01bd84..60f6c9402 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -27,6 +27,7 @@ #include "mme/s1ap.h" #include "mme/s1ap_nas_transport.h" #include "srslte/common/security.h" +#include "srslte/common/liblte_security.h" namespace srsepc{ @@ -1042,17 +1043,25 @@ s1ap_nas_transport::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, return false; } - //Generate MAC for integrity protection - //FIXME Write wrapper to support EIA1, EIA2, etc. + //Generate EPS security context uint8_t mac[4]; - srslte::security_generate_k_nas( ue_emm_ctx->security_ctxt.k_asme, srslte::CIPHERING_ALGORITHM_ID_EEA0, srslte::INTEGRITY_ALGORITHM_ID_128_EIA1, ue_emm_ctx->security_ctxt.k_nas_enc, ue_emm_ctx->security_ctxt.k_nas_int ); - + srslte::security_generate_k_nas( ue_emm_ctx->security_ctxt.k_asme, + srslte::CIPHERING_ALGORITHM_ID_EEA0, + srslte::INTEGRITY_ALGORITHM_ID_128_EIA1, + ue_emm_ctx->security_ctxt.k_nas_enc, + ue_emm_ctx->security_ctxt.k_nas_int + ); + uint8_t key_enb[32]; + liblte_security_generate_k_enb(ue_emm_ctx->security_ctxt.k_asme, ue_emm_ctx->security_ctxt.ul_nas_count, ue_emm_ctx->security_ctxt.k_enb); + m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",ue_emm_ctx->security_ctxt.ul_nas_count); + //Generate MAC for integrity protection + //FIXME Write wrapper to support EIA1, EIA2, etc. srslte::security_128_eia1 (&ue_emm_ctx->security_ctxt.k_nas_int[16], ue_emm_ctx->security_ctxt.dl_nas_count, 0, From b54efc6d9fa64f4d9ab8700c9006d7b642163c3c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Feb 2018 17:15:30 +0100 Subject: [PATCH 072/342] Added testing log info --- srsue/src/upper/rrc.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index f93401fc5..b5c44b391 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -2602,6 +2602,7 @@ void rrc::rrc_meas::calculate_triggers(uint32_t tti) } } if (gen_report) { + log_h->info("Generate report MeasId=%d, from event\n", m->first); generate_report(m->first); } } @@ -2631,6 +2632,7 @@ void rrc::rrc_meas::ho_finish() { bool rrc::rrc_meas::timer_expired(uint32_t timer_id) { for (std::map::iterator iter = active.begin(); iter != active.end(); ++iter) { if (iter->second.periodic_timer == timer_id) { + log_h->info("Generate report MeasId=%d, from timerId=%d\n", iter->first, timer_id); generate_report(iter->first); return true; } @@ -2814,6 +2816,8 @@ void rrc::rrc_meas::parse_meas_config(LIBLTE_RRC_MEAS_CONFIG_STRUCT *cfg) remove_meas_id(cfg->meas_id_to_remove_list[i]); } + log_h->info("nof active measId=%d\n", active.size()); + // Measurement identity addition/modification 5.5.2.3 if (cfg->meas_id_to_add_mod_list_present) { for (uint32_t i=0;imeas_id_to_add_mod_list.N_meas_id;i++) { @@ -2828,8 +2832,9 @@ void rrc::rrc_meas::parse_meas_config(LIBLTE_RRC_MEAS_CONFIG_STRUCT *cfg) } active[measId->meas_id].object_id = measId->meas_obj_id; active[measId->meas_id].report_id = measId->rep_cnfg_id; - log_h->info("MEAS: %s measId=%d, measObjectId=%d, reportConfigId=%d\n", - is_new?"Added":"Updated", measId->meas_id, measId->meas_obj_id, measId->rep_cnfg_id); + log_h->info("MEAS: %s measId=%d, measObjectId=%d, reportConfigId=%d, nof_values=%d\n", + is_new?"Added":"Updated", measId->meas_id, measId->meas_obj_id, measId->rep_cnfg_id, + active[measId->meas_id].cell_values.size()); } } From 7ae2975de44132c1e76813e74700aa9048a8ee94 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 14 Feb 2018 17:40:05 +0000 Subject: [PATCH 073/342] Starting to get M-TMSI from service request. --- srsepc/hdr/mme/s1ap_nas_transport.h | 6 ++ srsepc/src/mme/s1ap_nas_transport.cc | 99 +++++++++++++++++++++++++++- 2 files changed, 103 insertions(+), 2 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index 8d9b7429a..c36081ae2 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -65,6 +65,11 @@ public: srslte::byte_buffer_t *reply_buffer, bool* reply_flag, struct sctp_sndrcvinfo *enb_sri); + bool handle_nas_service_request(uint32_t m_tmsi, + srslte::byte_buffer_t *nas_msg, + srslte::byte_buffer_t *reply_buffer, + bool* reply_flag, + struct sctp_sndrcvinfo *enb_sri); bool handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag); bool handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); bool handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); @@ -73,6 +78,7 @@ public: bool handle_tracking_area_update_request(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag); bool integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_buffer_t *pdu); + bool short_integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_buffer_t *pdu); 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); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 60f6c9402..3377dd755 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -80,7 +80,7 @@ bool s1ap_nas_transport::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) { - LIBLTE_MME_SERVICE_REQUEST_MSG_STRUCT service_req; + //LIBLTE_MME_SERVICE_REQUEST_MSG_STRUCT service_req; m_s1ap_log->console("Received Initial UE Message.\n"); m_s1ap_log->info("Received Initial UE Message.\n"); @@ -107,7 +107,26 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA { m_s1ap_log->info("Received Service Request \n"); m_s1ap_log->console("Received Service Request \n"); - liblte_mme_unpack_service_request_msg((LIBLTE_BYTE_MSG_STRUCT*) nas_msg, &service_req); + if(!init_ue->S_TMSI_present) + { + m_s1ap_log->error("Service request -- S-TMSI not present\n "); + m_s1ap_log->console("Service request -- S-TMSI not present\n" ); + } + /* + typedef struct{ + bool ext; + LIBLTE_S1AP_MME_CODE_STRUCT mMEC; + LIBLTE_S1AP_M_TMSI_STRUCT m_TMSI; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; + }LIBLTE_S1AP_S_TMSI_STRUCT; + typedef struct{ + uint8_t buffer[4]; + }LIBLTE_S1AP_M_TMSI_STRUCT;*/ + uint32_t *m_tmsi = (uint32_t*) &init_ue->S_TMSI.m_TMSI.buffer; + m_s1ap_log->info("Service request -- S-TMSI 0x%x\n ", *m_tmsi); + m_s1ap_log->console("Service request -- S-TMSI 0x%x\n", *m_tmsi ); + handle_nas_service_request(*m_tmsi, nas_msg, reply_buffer,reply_flag, enb_sri); return false; } m_pool->deallocate(nas_msg); @@ -544,6 +563,52 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, return true; } +bool +s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, + srslte::byte_buffer_t *nas_msg, + srslte::byte_buffer_t *reply_buffer, + bool* reply_flag, + struct sctp_sndrcvinfo *enb_sri) +{ + + bool mac_valid = false; + LIBLTE_MME_SERVICE_REQUEST_MSG_STRUCT service_req; + + LIBLTE_ERROR_ENUM err = liblte_mme_unpack_service_request_msg((LIBLTE_BYTE_MSG_STRUCT*) nas_msg, &service_req); + if(err !=LIBLTE_SUCCESS) + { + m_s1ap_log->error("Could not unpack service request\n"); + return false; + } + + std::map::iterator it = m_s1ap->m_tmsi_to_imsi.find(m_tmsi); + if(it == m_s1ap->m_tmsi_to_imsi.end()) + { + m_s1ap_log->console("Could not find IMSI from M-TMSI\n"); + m_s1ap_log->error("Could not find IMSI from M-TMSI\n"); + //FIXME send service reject + return false; + } + + ue_emm_ctx_t *ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(it->second); + if(ue_emm_ctx == NULL) + { + m_s1ap_log->console("Could not find UE security context\n"); + m_s1ap_log->error("Could not find UE security context\n"); + //FIXME send service reject + return false; + } + mac_valid = short_integrity_check(ue_emm_ctx,nas_msg); + if(mac_valid) + m_s1ap_log->console("Banzai!!!\n"); + /* + typedef struct{ + LIBLTE_MME_KSI_AND_SEQUENCE_NUMBER_STRUCT ksi_and_seq_num; + uint16 short_mac; + }LIBLTE_MME_SERVICE_REQUEST_MSG_STRUCT; + */ + return true; +} bool s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag) { @@ -818,6 +883,36 @@ s1ap_nas_transport::handle_tracking_area_update_request(srslte::byte_buffer_t *n return true; } +bool +s1ap_nas_transport::short_integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_buffer_t *pdu) +{ + uint8_t exp_mac[2]; + uint8_t *mac = &pdu->msg[2]; + int i; + + srslte::security_128_eia1(&emm_ctx->security_ctxt.k_nas_int[16], + emm_ctx->security_ctxt.ul_nas_count, + 0, + SECURITY_DIRECTION_UPLINK, + &pdu->msg[0], + 2, + &exp_mac[0]); + + // Check if expected mac equals the sent mac + for(i=0; i<2; i++){ + if(exp_mac[i] != mac[i]){ + m_s1ap_log->warning("Short integrity check failure. Local: count=%d, [%02x %02x], " + "Received: count=%d, [%02x %02x]\n", + emm_ctx->security_ctxt.ul_nas_count, exp_mac[0], exp_mac[1], + pdu->msg[1] & 0x1F, mac[0], mac[1]); + return false; + } + } + m_s1ap_log->info("Integrity check ok. Local: count=%d, Received: count=%d\n", + emm_ctx->security_ctxt.ul_nas_count, pdu->msg[1] & 0x1F); + return true; +} + bool s1ap_nas_transport::integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_buffer_t *pdu) From 23e722f97ac96469e17ab7493a37ce523d686073 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Feb 2018 19:38:53 +0100 Subject: [PATCH 074/342] Fixed issue rsrp=0 in neighbour cell measurements --- srsue/src/upper/rrc.cc | 65 ++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index b5c44b391..ba2c45190 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -2539,6 +2539,8 @@ void rrc::rrc_meas::calculate_triggers(uint32_t tti) } } + + for (std::map::iterator m = active.begin(); m != active.end(); ++m) { report_cfg_t *cfg = &reports_cfg[m->second.report_id]; float hyst = 0.5*cfg->event.hysteresis; @@ -2563,41 +2565,48 @@ void rrc::rrc_meas::calculate_triggers(uint32_t tti) enter_condition = Mp + hyst < range_to_value(cfg->trigger_quantity, cfg->event.event_a1.eutra.range); exit_condition = Mp - hyst > range_to_value(cfg->trigger_quantity, cfg->event.event_a1.eutra.range); } + + // check only if gen_report |= process_event(&cfg->event, tti, enter_condition, exit_condition, - &m->second, &m->second.cell_values[serving_cell_idx]); + &m->second, &pcell_measurement); + if (gen_report) { + log_h->info("Triggered by A1/A2 event\n"); + } // Rest are evaluated for every cell in frequency } else { meas_obj_t *obj = &objects[m->second.object_id]; for (std::map::iterator cell = obj->cells.begin(); cell != obj->cells.end(); ++cell) { - float Ofn = obj->q_offset; - float Ocn = cell->second.q_offset; - float Mn = m->second.cell_values[cell->second.pci].ms[cfg->trigger_quantity]; - float Off=0, th=0, th1=0, th2=0; - bool enter_condition = false; - bool exit_condition = false; - switch (event_id) { - case LIBLTE_RRC_EVENT_ID_EUTRA_A3: - Off = 0.5*cfg->event.event_a3.offset; - enter_condition = Mn + Ofn + Ocn - hyst > Mp + Ofp + Ocp + Off; - exit_condition = Mn + Ofn + Ocn + hyst < Mp + Ofp + Ocp + Off; - break; - case LIBLTE_RRC_EVENT_ID_EUTRA_A4: - th = range_to_value(cfg->trigger_quantity, cfg->event.event_a4.eutra.range); - enter_condition = Mn + Ofn + Ocn - hyst > th; - exit_condition = Mn + Ofn + Ocn + hyst < th; - break; - case LIBLTE_RRC_EVENT_ID_EUTRA_A5: - th1 = range_to_value(cfg->trigger_quantity, cfg->event.event_a5.eutra1.range); - th2 = range_to_value(cfg->trigger_quantity, cfg->event.event_a5.eutra2.range); - enter_condition = (Mp + hyst < th1) && (Mn + Ofn + Ocn - hyst > th2); - exit_condition = (Mp - hyst > th1) && (Mn + Ofn + Ocn + hyst < th2); - break; - default: - log_h->error("Error event %s not implemented\n", event_str); + if (m->second.cell_values.count(cell->second.pci)) { + float Ofn = obj->q_offset; + float Ocn = cell->second.q_offset; + float Mn = m->second.cell_values[cell->second.pci].ms[cfg->trigger_quantity]; + float Off=0, th=0, th1=0, th2=0; + bool enter_condition = false; + bool exit_condition = false; + switch (event_id) { + case LIBLTE_RRC_EVENT_ID_EUTRA_A3: + Off = 0.5*cfg->event.event_a3.offset; + enter_condition = Mn + Ofn + Ocn - hyst > Mp + Ofp + Ocp + Off; + exit_condition = Mn + Ofn + Ocn + hyst < Mp + Ofp + Ocp + Off; + break; + case LIBLTE_RRC_EVENT_ID_EUTRA_A4: + th = range_to_value(cfg->trigger_quantity, cfg->event.event_a4.eutra.range); + enter_condition = Mn + Ofn + Ocn - hyst > th; + exit_condition = Mn + Ofn + Ocn + hyst < th; + break; + case LIBLTE_RRC_EVENT_ID_EUTRA_A5: + th1 = range_to_value(cfg->trigger_quantity, cfg->event.event_a5.eutra1.range); + th2 = range_to_value(cfg->trigger_quantity, cfg->event.event_a5.eutra2.range); + enter_condition = (Mp + hyst < th1) && (Mn + Ofn + Ocn - hyst > th2); + exit_condition = (Mp - hyst > th1) && (Mn + Ofn + Ocn + hyst < th2); + break; + default: + log_h->error("Error event %s not implemented\n", event_str); + } + gen_report |= process_event(&cfg->event, tti, enter_condition, exit_condition, + &m->second, &m->second.cell_values[cell->second.pci]); } - gen_report |= process_event(&cfg->event, tti, enter_condition, exit_condition, - &m->second, &m->second.cell_values[cell->second.pci]); } } } From 90de622f6c2fdaeb3ff39a3887a4f9ca1ac9b403 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Feb 2018 21:52:14 +0100 Subject: [PATCH 075/342] Fixed SIB searching --- srsue/src/upper/rrc.cc | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index f93401fc5..9ef892edb 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -341,11 +341,14 @@ void rrc::run_si_acquisition_procedure() // Instruct MAC to look for SIB1 tti = mac->get_current_tti(); si_win_start = sib_start_tti(tti, 2, 0, 5); - if (tti > last_win_start + 10) { + if (last_win_start == 0 || + (srslte_tti_interval(last_win_start, tti) > 20 && srslte_tti_interval(last_win_start, tti) < 1000)) + { + last_win_start = si_win_start; mac->bcch_start_rx(si_win_start, 1); - rrc_log->debug("Instructed MAC to search for SIB1, win_start=%d, win_len=%d\n", - si_win_start, 1); + rrc_log->info("Instructed MAC to search for SIB1, win_start=%d, win_len=%d, interval=%d\n", + si_win_start, 1, srslte_tti_interval(last_win_start, tti)); nof_sib1_trials++; if (nof_sib1_trials >= SIB1_SEARCH_TIMEOUT) { if (state == RRC_STATE_CELL_SELECTING) { @@ -369,13 +372,15 @@ void rrc::run_si_acquisition_procedure() tti = mac->get_current_tti(); period = liblte_rrc_si_periodicity_num[serving_cell->sib1.sched_info[sysinfo_index].si_periodicity]; si_win_start = sib_start_tti(tti, period, offset, sf); + si_win_len = liblte_rrc_si_window_length_num[serving_cell->sib1.si_window_length]; - if (tti > last_win_start + 10) { + if (last_win_start == 0 || + (srslte_tti_interval(last_win_start, tti) > period*10 && srslte_tti_interval(last_win_start, tti) < 1000)) + { last_win_start = si_win_start; - si_win_len = liblte_rrc_si_window_length_num[serving_cell->sib1.si_window_length]; mac->bcch_start_rx(si_win_start, si_win_len); - rrc_log->debug("Instructed MAC to search for system info, win_start=%d, win_len=%d\n", + rrc_log->info("Instructed MAC to search for system info, win_start=%d, win_len=%d\n", si_win_start, si_win_len); } @@ -1313,6 +1318,9 @@ void rrc::write_pdu_bcch_dlsch(byte_buffer_t *pdu) { handle_sib13(); } } + + last_win_start = 0; + if(serving_cell->has_valid_sib2) { sysinfo_index++; } From a2129601dfb9fd7064e85056c9f01459930eeb1b Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 15 Feb 2018 03:16:07 +0100 Subject: [PATCH 076/342] Noise level in MIMO is not divided by number of antennas --- lib/examples/pdsch_enodeb.c | 17 ++++++++++++++-- lib/src/phy/ch_estimation/chest_dl.c | 30 +++++++++++++++++----------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index c780e02ea..158d672ea 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -84,6 +84,8 @@ int mbsfn_area_id = -1; char *rf_args = ""; float rf_amp = 0.8, rf_gain = 70.0, rf_freq = 2400000000; +float output_file_snr = +INFINITY; + bool null_file_sink=false; srslte_filesink_t fsink; srslte_ofdm_t ifft[SRSLTE_MAX_PORTS]; @@ -145,13 +147,14 @@ void usage(char *prog) { printf("\t-w Number of codewords/layers (multiplex mode only)* [Default %d]\n", multiplex_nof_layers); printf("\t-u listen TCP port for input data (-1 is random) [Default %d]\n", net_port); printf("\t-v [set srslte_verbose to debug, default none]\n"); + printf("\t-s output file SNR [Default %f]\n", output_file_snr); printf("\n"); printf("\t*: See 3GPP 36.212 Table 5.3.3.1.5-4 for more information\n"); } void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "aglfmoncpvutxbwM")) != -1) { + while ((opt = getopt(argc, argv, "aglfmoncpvutxbwMs")) != -1) { switch (opt) { case 'a': @@ -200,6 +203,9 @@ void parse_args(int argc, char **argv) { case 'v': srslte_verbose++; break; + case 's': + output_file_snr = atof(argv[optind]); + break; default: usage(argv[0]); exit(-1); @@ -989,7 +995,14 @@ int main(int argc, char **argv) { /* send to file or usrp */ if (output_file_name) { if (!null_file_sink) { - srslte_filesink_write_multi(&fsink, (void**) output_buffer, sf_n_samples, cell.nof_ports); + /* Apply AWGN */ + if (output_file_snr != +INFINITY) { + float var = powf(10.0f, -(output_file_snr + 3.0f) / 20.0f); + for (int k = 0; k < cell.nof_ports; k++) { + srslte_ch_awgn_c(output_buffer[k], output_buffer[k], var, sf_n_samples); + } + } + srslte_filesink_write_multi(&fsink, (void**) output_buffer, sf_n_samples, cell.nof_ports); } usleep(1000); } else { diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index ba9ae40e6..5249696af 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -291,7 +291,7 @@ static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id, srslt norm /= norm3; } } - float power = norm*q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_noise, nref); + float power = norm*srslte_vec_avg_power_cf(q->tmp_noise, nref); return power; } @@ -543,7 +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); - q->rsrp[rxant_id][port_id] = __real__ srslte_vec_dot_prod_conj_ccc(q->pilot_estimates, q->pilot_estimates, npilots) / npilots; + q->rsrp[rxant_id][port_id] = srslte_vec_avg_power_cf(q->pilot_estimates, npilots); q->rssi[rxant_id][port_id] = srslte_chest_dl_rssi(q, input, port_id); } @@ -639,7 +639,10 @@ float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q) { for (int i=0;ilast_nof_antennas;i++) { n += srslte_vec_acc_ff(q->noise_estimate[i], q->cell.nof_ports)/q->cell.nof_ports; } - return n/q->last_nof_antennas; + if (q->last_nof_antennas) { + n /= q->last_nof_antennas; + } + return n; } float srslte_chest_dl_get_snr(srslte_chest_dl_t *q) { @@ -691,20 +694,23 @@ float srslte_chest_dl_get_rsrp_ant_port(srslte_chest_dl_t *q, uint32_t ant_idx, } float srslte_chest_dl_get_rsrp_port(srslte_chest_dl_t *q, uint32_t port) { - float max = -INFINITY; - for (int i = 0; i < q->last_nof_antennas; i++) { - if (q->rsrp[i][port] > max) { - max = q->rsrp[i][port]; - } + float sum = 0.0f; + for (int j = 0; j < q->cell.nof_ports; ++j) { + sum +=q->rsrp[port][j]; } - return max; + + if (q->cell.nof_ports) { + sum /= q->cell.nof_ports; + } + + return sum; } float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) { - float max = -INFINITY; - for (int i = 0; i < q->cell.nof_ports; ++i) { + float max = -0.0f; + for (int i = 0; i < q->last_nof_antennas; ++i) { float v = srslte_chest_dl_get_rsrp_port(q, i); - if (max < v) { + if (v > max) { max = v; } } From f4fba4e2f5062d2e0075546649636d9b2d9f13df Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 15 Feb 2018 11:58:46 +0000 Subject: [PATCH 077/342] Fixed ntohl bug in getting the service request m-tmsi. --- srsepc/src/mme/s1ap.cc | 2 +- srsepc/src/mme/s1ap_nas_transport.cc | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 31db87cf5..f72eb9bc4 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -517,7 +517,7 @@ s1ap::allocate_m_tmsi(uint64_t imsi) { uint32_t m_tmsi = m_next_m_tmsi++; m_tmsi_to_imsi.insert(std::pair(m_tmsi,imsi)); - m_s1ap_log->info("Allocated M-TMSI 0x%x,\n",m_tmsi); + m_s1ap_log->debug("Allocated M-TMSI 0x%x to IMSI %015ul,\n",m_tmsi,imsi); //uint32_t m_tmsi = 0x0123; return m_tmsi; } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 3377dd755..a40461064 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -124,9 +124,9 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA uint8_t buffer[4]; }LIBLTE_S1AP_M_TMSI_STRUCT;*/ uint32_t *m_tmsi = (uint32_t*) &init_ue->S_TMSI.m_TMSI.buffer; - m_s1ap_log->info("Service request -- S-TMSI 0x%x\n ", *m_tmsi); - m_s1ap_log->console("Service request -- S-TMSI 0x%x\n", *m_tmsi ); - handle_nas_service_request(*m_tmsi, nas_msg, reply_buffer,reply_flag, enb_sri); + m_s1ap_log->info("Service request -- S-TMSI 0x%x\n ", ntohl(*m_tmsi)); + m_s1ap_log->console("Service request -- S-TMSI 0x%x\n", ntohl(*m_tmsi) ); + handle_nas_service_request(ntohl(*m_tmsi), nas_msg, reply_buffer,reply_flag, enb_sri); return false; } m_pool->deallocate(nas_msg); @@ -584,8 +584,8 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, std::map::iterator it = m_s1ap->m_tmsi_to_imsi.find(m_tmsi); if(it == m_s1ap->m_tmsi_to_imsi.end()) { - m_s1ap_log->console("Could not find IMSI from M-TMSI\n"); - m_s1ap_log->error("Could not find IMSI from M-TMSI\n"); + m_s1ap_log->console("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); + m_s1ap_log->error("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); //FIXME send service reject return false; } From 094a7d272f56f4e325b58190865ac8b522c81797 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 15 Feb 2018 13:53:21 +0000 Subject: [PATCH 078/342] Fixed bug in short integrity check. Service request integrity check works now. --- srsepc/src/mme/s1ap_nas_transport.cc | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index a40461064..73891846d 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -112,17 +112,6 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA m_s1ap_log->error("Service request -- S-TMSI not present\n "); m_s1ap_log->console("Service request -- S-TMSI not present\n" ); } - /* - typedef struct{ - bool ext; - LIBLTE_S1AP_MME_CODE_STRUCT mMEC; - LIBLTE_S1AP_M_TMSI_STRUCT m_TMSI; - LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; - bool iE_Extensions_present; - }LIBLTE_S1AP_S_TMSI_STRUCT; - typedef struct{ - uint8_t buffer[4]; - }LIBLTE_S1AP_M_TMSI_STRUCT;*/ uint32_t *m_tmsi = (uint32_t*) &init_ue->S_TMSI.m_TMSI.buffer; m_s1ap_log->info("Service request -- S-TMSI 0x%x\n ", ntohl(*m_tmsi)); m_s1ap_log->console("Service request -- S-TMSI 0x%x\n", ntohl(*m_tmsi) ); @@ -598,6 +587,7 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, //FIXME send service reject return false; } + ue_emm_ctx->security_ctxt.ul_nas_count++; mac_valid = short_integrity_check(ue_emm_ctx,nas_msg); if(mac_valid) m_s1ap_log->console("Banzai!!!\n"); @@ -886,7 +876,7 @@ s1ap_nas_transport::handle_tracking_area_update_request(srslte::byte_buffer_t *n bool s1ap_nas_transport::short_integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_buffer_t *pdu) { - uint8_t exp_mac[2]; + uint8_t exp_mac[4]; uint8_t *mac = &pdu->msg[2]; int i; @@ -900,10 +890,10 @@ s1ap_nas_transport::short_integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_bu // Check if expected mac equals the sent mac for(i=0; i<2; i++){ - if(exp_mac[i] != mac[i]){ - m_s1ap_log->warning("Short integrity check failure. Local: count=%d, [%02x %02x], " + if(exp_mac[i+2] != mac[i]){ + m_s1ap_log->warning("Short integrity check failure. Local: count=%d, [%02x %02x %02x %02x], " "Received: count=%d, [%02x %02x]\n", - emm_ctx->security_ctxt.ul_nas_count, exp_mac[0], exp_mac[1], + emm_ctx->security_ctxt.ul_nas_count, exp_mac[0], exp_mac[1], exp_mac[2], exp_mac[3], pdu->msg[1] & 0x1F, mac[0], mac[1]); return false; } From b69854724781655fed8c3eadd9ae65c3c2d8d2c2 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Thu, 15 Feb 2018 16:39:56 +0000 Subject: [PATCH 079/342] Fix for first RLC tx after handover --- lib/src/upper/rlc_am.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 413a02ac1..e12138268 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -112,8 +112,10 @@ void rlc_am::reset() pthread_mutex_lock(&mutex); reordering_timeout.reset(); - if(tx_sdu) - tx_sdu->reset(); + if(tx_sdu) { + pool->deallocate(tx_sdu); + tx_sdu = NULL; + } if(rx_sdu) rx_sdu->reset(); From 2e90ce370b16470a0d089a6b6e9349daffc35914 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 15 Feb 2018 18:30:43 +0000 Subject: [PATCH 080/342] Starting to prepare MME UE context release request. --- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 30 +++++- srsepc/src/mme/s1ap_nas_transport.cc | 132 ++++++++++++++++++++++++-- 2 files changed, 153 insertions(+), 9 deletions(-) diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index b2654cedd..bfbcc4978 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -264,9 +264,11 @@ s1ap_ctx_mngmt_proc::handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_I } bool -s1ap_ctx_mngmt_proc::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ue_rel, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag) +s1ap_ctx_mngmt_proc::handle_ue_context_release_request(uint32_t mme_ue_s1ap_id, srslte::byte_buffer_t *reply_buffer) { + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT ue_rel_req; + uint32_t mme_ue_s1ap_id = ue_rel->MME_UE_S1AP_ID.MME_UE_S1AP_ID; m_s1ap_log->info("Received UE Context Release Request. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); m_s1ap_log->console("Received UE Context Release Request. MME-UE S1AP Id %d\n", mme_ue_s1ap_id); @@ -306,4 +308,30 @@ s1ap_ctx_mngmt_proc::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECON return true; } +bool +s1ap_ctx_mngmt_proc::pack_ue_context_release_request(uint32_t mme_ue_s1ap_id, srslte::byte_buffer_t *reply_buffer) +{ + + //Prepare reply PDU + LIBLTE_S1AP_S1AP_PDU_STRUCT pdu; + bzero(&pdu, sizeof(LIBLTE_S1AP_S1AP_PDU_STRUCT)); + pdu.choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE; + + LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *init = &pdu.choice.initiatingMessage; + init->procedureCode = LIBLTE_S1AP_PROC_ID_UECONTEXTRELEASEREQUEST; + init->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_INITIALCONTEXTRELEASEREQUEST; + + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ctx_rel_req = &init->choice.UEContextReleaseRequest; + + LIBLTE_ERROR_ENUM err = liblte_s1ap_pack_s1ap_pdu(&pdu, (LIBLTE_BYTE_MSG_STRUCT*)reply_buffer); + if(err != LIBLTE_SUCCESS) + { + m_s1ap_log->error("Could not pack Initial Context Setup Request Message\n"); + return false; + } + + return true; +} + + } //namespace srsepc diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 73891846d..3089e18c9 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -590,13 +590,26 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, ue_emm_ctx->security_ctxt.ul_nas_count++; mac_valid = short_integrity_check(ue_emm_ctx,nas_msg); if(mac_valid) - m_s1ap_log->console("Banzai!!!\n"); - /* - typedef struct{ - LIBLTE_MME_KSI_AND_SEQUENCE_NUMBER_STRUCT ksi_and_seq_num; - uint16 short_mac; - }LIBLTE_MME_SERVICE_REQUEST_MSG_STRUCT; - */ + { + m_s1ap_log->console("Service Request -- Short MAC valid\n"); + m_s1ap_log->info("Service Request -- Short MAC valid\n"); + ue_ecm_ctx_t ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(ue_emm_ctx.mme_ue_s1ap_id); + if(ecm_ctx !=NULL) + { + //Service request to Connected UE. + //Delete ECM context and connect. + m_mme_gtpc->send_delete_session_request(ue_ecm_ctx); + pack_context_release_request(); + } + else + { + //UE not connect. Connect normally. + } + else + { + m_s1ap_log->console("Service Request -- Short MAC invalid. Re-starting authentication procedure \n"); + m_s1ap_log->console("Service Request -- Short MAC invalid. Re-starting authentication procedure \n"); + } return true; } bool @@ -866,7 +879,110 @@ s1ap_nas_transport::handle_tracking_area_update_request(srslte::byte_buffer_t *n m_s1ap_log->console("Tracking area accept to MME-UE S1AP Id %d\n", ue_ecm_ctx->mme_ue_s1ap_id); LIBLTE_MME_TRACKING_AREA_UPDATE_ACCEPT_MSG_STRUCT tau_acc; - + + + bool t3412_present; + bool guti_present; + bool tai_list_present; + bool eps_bearer_context_status_present; + bool lai_present; + bool ms_id_present; + bool emm_cause_present; + bool t3402_present; + bool t3423_present; + bool equivalent_plmns_present; + bool emerg_num_list_present; + bool eps_network_feature_support_present; + bool additional_update_result_present; + bool t3412_ext_present; + + //Get decimal MCC and MNC + uint32_t mcc = 0; + mcc += 0x000F & m_s1ap->m_s1ap_args.mcc; + mcc += 10*( (0x00F0 & m_s1ap->m_s1ap_args.mcc) >> 4); + mcc += 100*( (0x0F00 & m_s1ap->m_s1ap_args.mcc) >> 8); + + uint32_t mnc = 0; + if( 0xFF00 == (m_s1ap->m_s1ap_args.mnc & 0xFF00 )) + { + //Two digit MNC + mnc += 0x000F & m_s1ap->m_s1ap_args.mnc; + mnc += 10*((0x00F0 & m_s1ap->m_s1ap_args.mnc) >> 4); + } + else + { + //Three digit MNC + mnc += 0x000F & m_s1ap->m_s1ap_args.mnc; + mnc += 10*((0x00F0 & m_s1ap->m_s1ap_args.mnc) >> 4); + mnc += 100*((0x0F00 & m_s1ap->m_s1ap_args.mnc) >> 8); + } + + //T3412 Timer + tau_acc.t3412_present = true; + tau_acc.t3412.unit = LIBLTE_MME_GPRS_TIMER_UNIT_1_MINUTE; // GPRS 1 minute unit + tau_acc.t3412.value = 30; // 30 minute periodic timer + + //GUTI + tau_acc.guti_present=true; + tau_acc.guti.type_of_id = 6; //110 -> GUTI + tau_acc.guti.guti.mcc = mcc; + tau_acc.guti.guti.mnc = mnc; + tau_acc.guti.guti.mme_group_id = m_s1ap->m_s1ap_args.mme_group; + tau_acc.guti.guti.mme_code = m_s1ap->m_s1ap_args.mme_code; + tau_acc.guti.guti.m_tmsi = 0xF000; + m_s1ap_log->debug("Allocated GUTI: MCC %d, MNC %d, MME Group Id %d, MME Code 0x%x, M-TMSI 0x%x\n", + tau_acc.guti.guti.mcc, + tau_acc.guti.guti.mnc, + tau_acc.guti.guti.mme_group_id, + tau_acc.guti.guti.mme_code, + tau_acc.guti.guti.m_tmsi); + + //Unused Options + tau_acc.t3402_present = false; + tau_acc.t3423_present = false; + tau_acc.equivalent_plmns_present = false; + tau_acc.emerg_num_list_present = false; + tau_acc.eps_network_feature_support_present = false; + tau_acc.additional_update_result_present = false; + tau_acc.t3412_ext_present = false; + + + //eps_update_result = LIBLTE_MME_TR + /* +typedef struct{ + LIBLTE_MME_GPRS_TIMER_STRUCT t3412; + LIBLTE_MME_EPS_MOBILE_ID_STRUCT guti; + LIBLTE_MME_TRACKING_AREA_IDENTITY_LIST_STRUCT tai_list; + LIBLTE_MME_EPS_BEARER_CONTEXT_STATUS_STRUCT eps_bearer_context_status; + LIBLTE_MME_LOCATION_AREA_ID_STRUCT lai; + LIBLTE_MME_MOBILE_ID_STRUCT ms_id; + LIBLTE_MME_GPRS_TIMER_STRUCT t3402; + LIBLTE_MME_GPRS_TIMER_STRUCT t3423; + LIBLTE_MME_PLMN_LIST_STRUCT equivalent_plmns; + LIBLTE_MME_EMERGENCY_NUMBER_LIST_STRUCT emerg_num_list; + LIBLTE_MME_EPS_NETWORK_FEATURE_SUPPORT_STRUCT eps_network_feature_support; + LIBLTE_MME_GPRS_TIMER_3_STRUCT t3412_ext; + LIBLTE_MME_ADDITIONAL_UPDATE_RESULT_ENUM additional_update_result; + uint8 eps_update_result; + uint8 emm_cause; + bool t3412_present; + bool guti_present; + bool tai_list_present; + bool eps_bearer_context_status_present; + bool lai_present; + bool ms_id_present; + bool emm_cause_present; + bool t3402_present; + bool t3423_present; + bool equivalent_plmns_present; + bool emerg_num_list_present; + bool eps_network_feature_support_present; + bool additional_update_result_present; + bool t3412_ext_present;v +}LIBLTE_MME_TRACKING_AREA_UPDATE_ACCEPT_MSG_STRUCT; + */ + + //Send reply to eNB //*reply_flag = true; From 24d394d8ca66869178ee2e611f5e238ca13f655f Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 15 Feb 2018 18:47:56 +0000 Subject: [PATCH 081/342] Fixed some compilation issues. --- srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h | 1 + srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 16 +++++++++++++--- srsepc/src/mme/s1ap_nas_transport.cc | 7 ++++--- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h index 2eaca64ab..2e448f110 100644 --- a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h @@ -50,6 +50,7 @@ public: bool send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte::gtpc_create_session_response *cs_resp, struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid); bool handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *in_ctxt_resp); bool handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ue_rel, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); + bool pack_ue_context_release_request(uint32_t mme_ue_s1ap_id, srslte::byte_buffer_t *reply_buffer); private: s1ap_ctx_mngmt_proc(); diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index bfbcc4978..527f310b5 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -264,7 +264,7 @@ s1ap_ctx_mngmt_proc::handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_I } bool -s1ap_ctx_mngmt_proc::handle_ue_context_release_request(uint32_t mme_ue_s1ap_id, srslte::byte_buffer_t *reply_buffer) +s1ap_ctx_mngmt_proc::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ue_rel, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag) { LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT ue_rel_req; @@ -319,10 +319,20 @@ s1ap_ctx_mngmt_proc::pack_ue_context_release_request(uint32_t mme_ue_s1ap_id, sr LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *init = &pdu.choice.initiatingMessage; init->procedureCode = LIBLTE_S1AP_PROC_ID_UECONTEXTRELEASEREQUEST; - init->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_INITIALCONTEXTRELEASEREQUEST; + init->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECONTEXTRELEASEREQUEST; LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ctx_rel_req = &init->choice.UEContextReleaseRequest; - + + /* + typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_CAUSE_STRUCT Cause; + LIBLTE_S1AP_GWCONTEXTRELEASEINDICATION_ENUM_EXT GWContextReleaseIndication; + bool GWContextReleaseIndication_present; + }LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT; + */ LIBLTE_ERROR_ENUM err = liblte_s1ap_pack_s1ap_pdu(&pdu, (LIBLTE_BYTE_MSG_STRUCT*)reply_buffer); if(err != LIBLTE_SUCCESS) { diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 3089e18c9..af7d785cb 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -593,18 +593,19 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, { m_s1ap_log->console("Service Request -- Short MAC valid\n"); m_s1ap_log->info("Service Request -- Short MAC valid\n"); - ue_ecm_ctx_t ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(ue_emm_ctx.mme_ue_s1ap_id); + ue_ecm_ctx_t *ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(ue_emm_ctx->mme_ue_s1ap_id); if(ecm_ctx !=NULL) { //Service request to Connected UE. //Delete ECM context and connect. - m_mme_gtpc->send_delete_session_request(ue_ecm_ctx); - pack_context_release_request(); + m_mme_gtpc->send_delete_session_request(ecm_ctx); + //pack_context_release_request(); } else { //UE not connect. Connect normally. } + } else { m_s1ap_log->console("Service Request -- Short MAC invalid. Re-starting authentication procedure \n"); From 48278c4c066a060c39f8054e0e19c449f7d653f4 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 16 Feb 2018 10:25:57 +0100 Subject: [PATCH 082/342] deallocate sdu in rlc_am_test --- lib/test/upper/rlc_am_test.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index 0b8c63668..b690210a9 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -64,6 +64,7 @@ public: { assert(lcid == 1); sdus[n_sdus++] = sdu; + 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) {} From f86bebb0f3c746b61bea099c3cc182fd3020a16b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 16 Feb 2018 11:23:58 +0100 Subject: [PATCH 083/342] Revert "deallocate sdu in rlc_am_test" This reverts commit 48278c4c066a060c39f8054e0e19c449f7d653f4. --- lib/test/upper/rlc_am_test.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index b690210a9..0b8c63668 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -64,7 +64,6 @@ public: { assert(lcid == 1); sdus[n_sdus++] = sdu; - 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) {} From 90fe4a218bb82e8275b5ea4a8ebcb2a980990de4 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 16 Feb 2018 11:37:57 +0100 Subject: [PATCH 084/342] Fix RNTI in Msg3 after non-contention HO in PCAP --- srsue/hdr/mac/ul_harq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index 4ea37cb07..60deff36f 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -272,7 +272,7 @@ private: generate_retx(tti_tx, action); } if (harq_entity->pcap && grant) { - if (grant->is_from_rar) { + if (grant->is_from_rar && harq_entity->rntis->temp_rnti) { grant->rnti = harq_entity->rntis->temp_rnti; } harq_entity->pcap->write_ul_crnti(pdu_ptr, grant->n_bytes[0], grant->rnti, get_nof_retx(), tti_tx); From 9a8257048d71a6186b1c9594faf4998e13007c32 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 16 Feb 2018 12:04:10 +0100 Subject: [PATCH 085/342] Casted phy_log vector to srslte::log --- srsue/src/phy/phy.cc | 2 +- srsue/src/ue.cc | 4 ++-- srsue/test/mac/mac_test.cc | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 820cf1351..07337b022 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -120,7 +120,7 @@ bool phy::check_args(phy_args_t *args) } bool phy::init(srslte::radio_multi* radio_handler, mac_interface_phy *mac, rrc_interface_phy *rrc, - std::vector log_vec, phy_args_t *phy_args) { + std::vector log_vec, phy_args_t *phy_args) { mlockall(MCL_CURRENT | MCL_FUTURE); diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 611bac620..2f8fa5794 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -68,7 +68,7 @@ bool ue::init(all_args_t *args_) char tmp[16]; sprintf(tmp, "PHY%d",i); mylog->init(tmp, logger, true); - phy_log.push_back((void*) mylog); + phy_log.push_back(mylog); } mac_log.init("MAC ", logger, true); @@ -91,7 +91,7 @@ bool ue::init(all_args_t *args_) char tmp[16]; sprintf(tmp, "PHY_LIB"); lib_log->init(tmp, logger, true); - phy_log.push_back((void*) lib_log); + phy_log.push_back(lib_log); ((srslte::log_filter*) phy_log[args->expert.phy.nof_phy_threads])->set_level(level(args->log.phy_lib_level)); diff --git a/srsue/test/mac/mac_test.cc b/srsue/test/mac/mac_test.cc index 324189427..b76ab2f95 100644 --- a/srsue/test/mac/mac_test.cc +++ b/srsue/test/mac/mac_test.cc @@ -451,12 +451,12 @@ int main(int argc, char *argv[]) exit(1); } - std::vector phy_log; + std::vector phy_log; srslte::log_filter *mylog = new srslte::log_filter("PHY"); char tmp[16]; sprintf(tmp, "PHY%d",0); - phy_log.push_back((void*) mylog); + phy_log.push_back((srslte::log*) mylog); switch (prog_args.verbose) { case 1: From 097005684aab2b42c95f5b92d1bdcc605df123d2 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 16 Feb 2018 12:05:45 +0100 Subject: [PATCH 086/342] Logs to test snr drop issue --- srsue/hdr/phy/phch_worker.h | 3 +++ srsue/src/phy/phch_recv.cc | 5 +++-- srsue/src/phy/phch_worker.cc | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index c154ff514..78389ccf7 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -70,6 +70,9 @@ public: void start_plot(); float get_ref_cfo(); + float get_snr(); + float get_rsrp(); + float get_noise(); float get_cfo(); float get_ul_cfo(); diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index bf09f5f34..80c972266 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -675,10 +675,11 @@ void phch_recv::run_thread() case 1: if (last_worker) { - Debug("SF: cfo_tot=%7.1f Hz, ref=%f Hz, pss=%f Hz\n", + Info("SF: cfo_tot=%7.1f Hz, ref=%f Hz, pss=%f Hz, snr_sf=%.2f dB, rsrp=%.2f dB, noise=%.2f dB\n", srslte_ue_sync_get_cfo(&ue_sync), 15000*last_worker->get_ref_cfo(), - 15000*ue_sync.strack.cfo_pss_mean); + 15000*ue_sync.strack.cfo_pss_mean, + last_worker->get_snr(), last_worker->get_rsrp(), last_worker->get_noise()); } last_worker = worker; diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index f7e1381f8..e6fb7f35a 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -203,6 +203,22 @@ float phch_worker::get_ref_cfo() return srslte_chest_dl_get_cfo(&ue_dl.chest); } +float phch_worker::get_snr() +{ + return 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)); +} + +float phch_worker::get_rsrp() +{ + return 10*log10(srslte_chest_dl_get_rsrp(&ue_dl.chest)); +} + +float phch_worker::get_noise() +{ + return 10*log10(srslte_chest_dl_get_noise_estimate(&ue_dl.chest)); +} + + float phch_worker::get_cfo() { return cfo; From 75f42ac82955fa55d4925f3805495d676f6d34e5 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 16 Feb 2018 12:40:07 +0100 Subject: [PATCH 087/342] add RLC AM destructor --- lib/include/srslte/upper/rlc_am.h | 1 + lib/src/upper/rlc_am.cc | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/lib/include/srslte/upper/rlc_am.h b/lib/include/srslte/upper/rlc_am.h index 2311b23cb..7601baefa 100644 --- a/lib/include/srslte/upper/rlc_am.h +++ b/lib/include/srslte/upper/rlc_am.h @@ -71,6 +71,7 @@ class rlc_am { public: rlc_am(); + ~rlc_am(); void init(log *rlc_entity_log_, uint32_t lcid_, srsue::pdcp_interface_rlc *pdcp_, diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 413a02ac1..652970011 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -68,6 +68,20 @@ rlc_am::rlc_am() : tx_sdu_queue(16) do_status = false; } +rlc_am::~rlc_am() +{ + // reset RLC and dealloc SDUs + stop(); + + if(rx_sdu) { + pool->deallocate(rx_sdu); + } + + if(tx_sdu) { + pool->deallocate(tx_sdu); + } +} + void rlc_am::init(srslte::log *log_, uint32_t lcid_, srsue::pdcp_interface_rlc *pdcp_, From b5b1c0bf4b53aae7ebbb64c5ef0f6efe3ca16e4d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 16 Feb 2018 12:41:13 +0100 Subject: [PATCH 088/342] fix memory leaks RLC AM test --- lib/test/upper/rlc_am_test.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index 0b8c63668..184de3a00 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -59,6 +59,14 @@ public: n_sdus = 0; } + ~rlc_am_tester(){ + for (uint32_t i = 0; i < 10; i++) { + if (sdus[i] != NULL) { + byte_buffer_pool::get_instance()->deallocate(sdus[i]); + } + } + } + // PDCP interface void write_pdu(uint32_t lcid, byte_buffer_t *sdu) { @@ -1051,21 +1059,31 @@ void resegment_test_6() int main(int argc, char **argv) { basic_test(); byte_buffer_pool::get_instance()->cleanup(); + concat_test(); byte_buffer_pool::get_instance()->cleanup(); + segment_test(); byte_buffer_pool::get_instance()->cleanup(); + retx_test(); byte_buffer_pool::get_instance()->cleanup(); + resegment_test_1(); byte_buffer_pool::get_instance()->cleanup(); + resegment_test_2(); byte_buffer_pool::get_instance()->cleanup(); + resegment_test_3(); byte_buffer_pool::get_instance()->cleanup(); + resegment_test_4(); byte_buffer_pool::get_instance()->cleanup(); + resegment_test_5(); byte_buffer_pool::get_instance()->cleanup(); + resegment_test_6(); + byte_buffer_pool::get_instance()->cleanup(); } From 315c5de06ca43d9ba58b8e799ccfc1e8905c45a2 Mon Sep 17 00:00:00 2001 From: yagoda Date: Fri, 16 Feb 2018 13:51:32 +0000 Subject: [PATCH 089/342] fixing type mismatch error in phy.h --- srsue/hdr/phy/phy.h | 4 ++-- srsue/hdr/ue.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index 53d4f6e13..a29480ad4 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -53,7 +53,7 @@ public: bool init(srslte::radio_multi *radio_handler, mac_interface_phy *mac, rrc_interface_phy *rrc, - std::vector log_vec, + std::vector log_vec, phy_args_t *args = NULL); void stop(); @@ -159,7 +159,7 @@ private: const static int WORKERS_THREAD_PRIO = 0; srslte::radio_multi *radio_handler; - std::vector log_vec; + std::vector log_vec; srslte::log *log_h; srslte::log *log_phy_lib_h; srsue::mac_interface_phy *mac; diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index 763531261..e36277461 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -101,7 +101,7 @@ private: srslte::logger *logger; // rf_log is on ue_base - std::vector phy_log; + std::vector phy_log; srslte::log_filter mac_log; srslte::log_filter rlc_log; srslte::log_filter pdcp_log; From 79e59f1bf85af1bb01fca1b50afa03e00267450d Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 16 Feb 2018 15:25:53 +0100 Subject: [PATCH 090/342] Missed headers in previous commit --- srsue/hdr/phy/phy.h | 4 ++-- srsue/hdr/ue.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index 53d4f6e13..a29480ad4 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -53,7 +53,7 @@ public: bool init(srslte::radio_multi *radio_handler, mac_interface_phy *mac, rrc_interface_phy *rrc, - std::vector log_vec, + std::vector log_vec, phy_args_t *args = NULL); void stop(); @@ -159,7 +159,7 @@ private: const static int WORKERS_THREAD_PRIO = 0; srslte::radio_multi *radio_handler; - std::vector log_vec; + std::vector log_vec; srslte::log *log_h; srslte::log *log_phy_lib_h; srsue::mac_interface_phy *mac; diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index 763531261..e36277461 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -101,7 +101,7 @@ private: srslte::logger *logger; // rf_log is on ue_base - std::vector phy_log; + std::vector phy_log; srslte::log_filter mac_log; srslte::log_filter rlc_log; srslte::log_filter pdcp_log; From 056e3793477a6ed14520380ec179967565adcfc5 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 16 Feb 2018 16:09:07 +0100 Subject: [PATCH 091/342] Set TA to time_adv instead of nsamples --- srsue/src/phy/phch_recv.cc | 9 ++------- srsue/src/phy/phy.cc | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 80c972266..bda9fbd69 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -186,14 +186,9 @@ void phch_recv::set_agc_enable(bool enable) } } -void phch_recv::set_time_adv_sec(float _time_adv_sec) +void phch_recv::set_time_adv_sec(float time_adv_sec) { - if (TX_MODE_CONTINUOUS && !radio_h->is_first_of_burst()) { - int nsamples = ceil(current_srate*_time_adv_sec); - next_offset = -nsamples; - } else { - time_adv_sec = _time_adv_sec; - } + this->time_adv_sec = time_adv_sec; } void phch_recv::set_ue_sync_opts(srslte_ue_sync_t *q, float cfo) diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 07337b022..84cd0fd08 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -226,7 +226,7 @@ void phy::set_timeadv_rar(uint32_t ta_cmd) { void phy::set_timeadv(uint32_t ta_cmd) { uint32_t new_nta = srslte_N_ta_new(n_ta, ta_cmd); - sf_recv.set_time_adv_sec(((float) (new_nta - n_ta))*SRSLTE_LTE_TS); + sf_recv.set_time_adv_sec(((float) new_nta)*SRSLTE_LTE_TS); Info("PHY: Set TA: ta_cmd: %d, n_ta: %d, old_n_ta: %d, ta_usec: %.1f\n", ta_cmd, new_nta, n_ta, ((float) new_nta)*SRSLTE_LTE_TS*1e6); n_ta = new_nta; } From e6dcb81d99138982893a2c2e62cdaf93d34aaf64 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 16 Feb 2018 16:37:36 +0100 Subject: [PATCH 092/342] Ignore TA cmd --- srsue/src/phy/phy.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 84cd0fd08..4417beb86 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -226,7 +226,7 @@ void phy::set_timeadv_rar(uint32_t ta_cmd) { void phy::set_timeadv(uint32_t ta_cmd) { uint32_t new_nta = srslte_N_ta_new(n_ta, ta_cmd); - sf_recv.set_time_adv_sec(((float) new_nta)*SRSLTE_LTE_TS); + //sf_recv.set_time_adv_sec(((float) new_nta)*SRSLTE_LTE_TS); Info("PHY: Set TA: ta_cmd: %d, n_ta: %d, old_n_ta: %d, ta_usec: %.1f\n", ta_cmd, new_nta, n_ta, ((float) new_nta)*SRSLTE_LTE_TS*1e6); n_ta = new_nta; } From 62116bf1aee150df3777ac0338ed52d9851eb3bf Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 16 Feb 2018 17:16:03 +0100 Subject: [PATCH 093/342] Revert "Logs to test snr drop issue" This reverts commit 097005684aab2b42c95f5b92d1bdcc605df123d2. --- srsue/hdr/phy/phch_worker.h | 3 --- srsue/src/phy/phch_recv.cc | 5 ++--- srsue/src/phy/phch_worker.cc | 16 ---------------- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index 78389ccf7..c154ff514 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -70,9 +70,6 @@ public: void start_plot(); float get_ref_cfo(); - float get_snr(); - float get_rsrp(); - float get_noise(); float get_cfo(); float get_ul_cfo(); diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index bda9fbd69..72afb5e1e 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -670,11 +670,10 @@ void phch_recv::run_thread() case 1: if (last_worker) { - Info("SF: cfo_tot=%7.1f Hz, ref=%f Hz, pss=%f Hz, snr_sf=%.2f dB, rsrp=%.2f dB, noise=%.2f dB\n", + Debug("SF: cfo_tot=%7.1f Hz, ref=%f Hz, pss=%f Hz\n", srslte_ue_sync_get_cfo(&ue_sync), 15000*last_worker->get_ref_cfo(), - 15000*ue_sync.strack.cfo_pss_mean, - last_worker->get_snr(), last_worker->get_rsrp(), last_worker->get_noise()); + 15000*ue_sync.strack.cfo_pss_mean); } last_worker = worker; diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index e6fb7f35a..f7e1381f8 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -203,22 +203,6 @@ float phch_worker::get_ref_cfo() return srslte_chest_dl_get_cfo(&ue_dl.chest); } -float phch_worker::get_snr() -{ - return 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)); -} - -float phch_worker::get_rsrp() -{ - return 10*log10(srslte_chest_dl_get_rsrp(&ue_dl.chest)); -} - -float phch_worker::get_noise() -{ - return 10*log10(srslte_chest_dl_get_noise_estimate(&ue_dl.chest)); -} - - float phch_worker::get_cfo() { return cfo; From 42c4b97f7e35bce0687671c696275fc2031e51c5 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 16 Feb 2018 17:59:48 +0100 Subject: [PATCH 094/342] Stop PDCCH RX before HO --- srsue/src/upper/rrc.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 4e8897dc1..4d93c9452 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1089,6 +1089,7 @@ bool rrc::ho_prepare() { ho_src_rnti = uernti.crnti; // Reset/Reestablish stack + mac->bcch_stop_rx(); // FIXME: change function name phy->meas_reset(); mac->wait_uplink(); pdcp->reestablish(); From bf691e8c65dee2a54c2f1fae19a4a431aed9132f Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 16 Feb 2018 18:14:00 +0100 Subject: [PATCH 095/342] Do not stop RX during HO --- srsue/src/phy/phch_recv.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 72afb5e1e..6016f3e91 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -384,11 +384,13 @@ bool phch_recv::cell_handover(srslte_cell_t cell) this->cell = cell; Info("Cell HO: Stopping sync with current cell\n"); worker_com->reset_ul(); - stop_sync(); + //stop_sync(); Info("Cell HO: Reconfiguring cell\n"); if (set_cell()) { Info("Cell HO: Synchronizing with new cell\n"); - resync_sfn(true, true); + //resync_sfn(true, true); + sfn_p.reset(); + phy_state = CELL_RESELECT; ret = true; } else { log_h->error("Cell HO: Configuring cell PCI=%d\n", cell.id); From e59822f9a982295095d26519b44eca79e4df8e0c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 16 Feb 2018 18:41:38 +0100 Subject: [PATCH 096/342] Fixed bug in previous commit --- srsue/hdr/phy/phch_recv.h | 5 ++-- srsue/src/phy/phch_recv.cc | 52 ++++++++++++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index 66c3342fb..bc7255ac9 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -309,10 +309,11 @@ private: CELL_SELECT, CELL_RESELECT, CELL_MEASURE, - CELL_CAMP + CELL_CAMP, + IDLE_RX } phy_state; - bool is_in_idle; + bool is_in_idle, is_in_idle_rx; // Sampling rate mode (find is 1.96 MHz, camp is the full cell BW) enum { diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 6016f3e91..8b913c1d3 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -380,20 +380,30 @@ bool phch_recv::cell_handover(srslte_cell_t cell) log_h->info("Cell HO: Waiting pending PHICH\n"); } - bool ret; + bool ret = false; this->cell = cell; Info("Cell HO: Stopping sync with current cell\n"); worker_com->reset_ul(); - //stop_sync(); - Info("Cell HO: Reconfiguring cell\n"); - if (set_cell()) { - Info("Cell HO: Synchronizing with new cell\n"); - //resync_sfn(true, true); - sfn_p.reset(); - phy_state = CELL_RESELECT; - ret = true; + phy_state = IDLE_RX; + cnt = 0; + while(!is_in_idle_rx && cnt<20) { + usleep(1000); + cnt++; + } + if (is_in_idle_rx) { + Info("Cell HO: Reconfiguring cell\n"); + if (set_cell()) { + //resync_sfn(true, true); + sfn_p.reset(); + phy_state = CELL_RESELECT; + Info("Cell HO: Synchronizing with new cell\n"); + ret = true; + } else { + log_h->error("Cell HO: Configuring cell PCI=%d\n", cell.id); + ret = false; + } } else { - log_h->error("Cell HO: Configuring cell PCI=%d\n", cell.id); + log_h->error("Cell HO: Could not stop sync\n"); ret = false; } return ret; @@ -574,6 +584,7 @@ void phch_recv::run_thread() uint32_t sf_idx = 0; phy_state = IDLE; is_in_idle = true; + is_in_idle_rx = false; while (running) { @@ -582,6 +593,10 @@ void phch_recv::run_thread() Debug("SYNC: state=%d\n", phy_state); } + if (phy_state != IDLE_RX) { + is_in_idle_rx = false; + } + log_h->step(tti); log_phy_lib_h->step(tti); @@ -746,6 +761,23 @@ void phch_recv::run_thread() is_in_idle = true; usleep(1000); break; + case IDLE_RX: + if (!worker) { + worker = (phch_worker *) workers_pool->wait_worker(tti); + } + is_in_idle_rx = true; + if (worker) { + for (uint32_t i = 0; i < SRSLTE_MAX_PORTS; i++) { + buffer[i] = worker->get_buffer(i); + } + if (!radio_h->rx_now(buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb), NULL)) { + Error("SYNC: Receiving from radio while in IDLE_RX\n"); + } + } else { + // wait_worker() only returns NULL if it's being closed. Quit now to avoid unnecessary loops here + running = false; + } + break; } // Increase TTI counter and trigger MAC clock (lower priority) From 2cb1f27ddb812a111a3e6e582afe7524ee9ccf4a Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 16 Feb 2018 17:47:55 +0000 Subject: [PATCH 097/342] Adding UE context release command. Fixing issue when identity response is integrity protected. --- srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h | 2 +- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 38 ++++++++++++++++----------- srsepc/src/mme/s1ap_mngmt_proc.cc | 6 +++-- srsepc/src/mme/s1ap_nas_transport.cc | 30 ++++++++++++++------- 4 files changed, 49 insertions(+), 27 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h index 2e448f110..9979b6594 100644 --- a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h @@ -50,7 +50,7 @@ public: bool send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte::gtpc_create_session_response *cs_resp, struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid); bool handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *in_ctxt_resp); bool handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ue_rel, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); - bool pack_ue_context_release_request(uint32_t mme_ue_s1ap_id, srslte::byte_buffer_t *reply_buffer); + bool send_ue_context_release_command(ue_ecm_ctx_t *ecm_ctx, srslte::byte_buffer_t *reply_buffer); private: s1ap_ctx_mngmt_proc(); diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 527f310b5..ba9d38577 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -309,36 +309,44 @@ s1ap_ctx_mngmt_proc::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECON } bool -s1ap_ctx_mngmt_proc::pack_ue_context_release_request(uint32_t mme_ue_s1ap_id, srslte::byte_buffer_t *reply_buffer) +s1ap_ctx_mngmt_proc::send_ue_context_release_command(ue_ecm_ctx_t *ecm_ctx, srslte::byte_buffer_t *reply_buffer) { + int s1mme = m_s1ap->get_s1_mme(); + //Prepare reply PDU LIBLTE_S1AP_S1AP_PDU_STRUCT pdu; bzero(&pdu, sizeof(LIBLTE_S1AP_S1AP_PDU_STRUCT)); pdu.choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE; LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *init = &pdu.choice.initiatingMessage; - init->procedureCode = LIBLTE_S1AP_PROC_ID_UECONTEXTRELEASEREQUEST; - init->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECONTEXTRELEASEREQUEST; + init->procedureCode = LIBLTE_S1AP_PROC_ID_UECONTEXTRELEASE; + init->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECONTEXTRELEASECOMMAND; + + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMMAND_STRUCT *ctx_rel_cmd = &init->choice.UEContextReleaseCommand; + + ctx_rel_cmd->UE_S1AP_IDs.choice_type = LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_UE_S1AP_ID_PAIR; + ctx_rel_cmd->UE_S1AP_IDs.choice.uE_S1AP_ID_pair.mME_UE_S1AP_ID.MME_UE_S1AP_ID = ecm_ctx->mme_ue_s1ap_id; + ctx_rel_cmd->UE_S1AP_IDs.choice.uE_S1AP_ID_pair.eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ecm_ctx->enb_ue_s1ap_id; + + ctx_rel_cmd->Cause.choice_type = LIBLTE_S1AP_CAUSE_CHOICE_NAS; + ctx_rel_cmd->Cause.choice.nas.ext = false; + ctx_rel_cmd->Cause.choice.nas.e = LIBLTE_S1AP_CAUSENAS_NORMAL_RELEASE; - LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ctx_rel_req = &init->choice.UEContextReleaseRequest; - - /* - typedef struct{ - bool ext; - LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; - LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; - LIBLTE_S1AP_CAUSE_STRUCT Cause; - LIBLTE_S1AP_GWCONTEXTRELEASEINDICATION_ENUM_EXT GWContextReleaseIndication; - bool GWContextReleaseIndication_present; - }LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT; - */ LIBLTE_ERROR_ENUM err = liblte_s1ap_pack_s1ap_pdu(&pdu, (LIBLTE_BYTE_MSG_STRUCT*)reply_buffer); if(err != LIBLTE_SUCCESS) { m_s1ap_log->error("Could not pack Initial Context Setup Request Message\n"); return false; } + //Send Reply to eNB + int n_sent = sctp_send(s1mme,reply_buffer->msg, reply_buffer->N_bytes, &ecm_ctx->enb_sri, 0); + if(n_sent == -1) + { + m_s1ap_log->error("Failed to send Initial Context Setup Request\n"); + return false; + } + return true; } diff --git a/srsepc/src/mme/s1ap_mngmt_proc.cc b/srsepc/src/mme/s1ap_mngmt_proc.cc index 8fa469ec3..43fa5d860 100644 --- a/srsepc/src/mme/s1ap_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_mngmt_proc.cc @@ -234,7 +234,7 @@ s1ap_mngmt_proc::pack_s1_setup_response(s1ap_args_t s1ap_args, srslte::byte_buff LIBLTE_S1AP_SERVEDGUMMEISITEM_STRUCT *serv_gummei = &s1_resp->ServedGUMMEIs.buffer[0]; serv_gummei->ext=false; - //serv_gummei->iE_Extensions=false; + serv_gummei->iE_Extensions_present = false; uint32_t plmn=0; srslte::s1ap_mccmnc_to_plmn(s1ap_args.mcc, s1ap_args.mnc, &plmn); @@ -257,7 +257,9 @@ s1ap_mngmt_proc::pack_s1_setup_response(s1ap_args_t s1ap_args, srslte::byte_buff //Relay Unsupported s1_resp->MMERelaySupportIndicator_present=false; - + + s1_resp->CriticalityDiagnostics_present = false; + liblte_s1ap_pack_s1ap_pdu(&pdu, (LIBLTE_BYTE_MSG_STRUCT*)msg); return true; diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index af7d785cb..8dd6c6e68 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -158,15 +158,27 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); if(ue_emm_ctx == NULL) { - m_s1ap_log->warning("Uplink NAS: could not find security context for integrity protected message. MME-UE S1AP id: %lu\n",mme_ue_s1ap_id); - m_pool->deallocate(nas_msg); - return false; + //No EMM context found. + //Perhaps a temporary context is being created? + //This can happen with integrity protected identity reponse and authentication response messages + if( !(msg_type == LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE && sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY) && + !(msg_type == LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE && sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY)) + { + m_s1ap_log->warning("Uplink NAS: could not find security context for integrity protected message. MME-UE S1AP id: %lu\n",mme_ue_s1ap_id); + m_pool->deallocate(nas_msg); + return false; + } } } - if(sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS) + if( sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS || + (msg_type == LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE && sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY) || + (msg_type == LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE && sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY)) { - //Plain NAS, only identity response is valid. + //Only identity response and authentication response are valid as plain NAS. + //Sometimes authentication response and identity are sent as integrity protected, + //but these messages are sent when the securty context is not setup yet, so we cannot integrity check it. + //FIXME Double-check switch(msg_type) { case LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE: @@ -220,17 +232,17 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA //Integrity protected NAS message, possibly chiphered. ue_emm_ctx->security_ctxt.ul_nas_count++; mac_valid = integrity_check(ue_emm_ctx,nas_msg); - if(!mac_valid && msg_type != LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE){ + if(!mac_valid){ m_s1ap_log->warning("Invalid MAC in NAS message type 0x%x.\n", msg_type); m_pool->deallocate(nas_msg); return false; } switch (msg_type) { - case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE: + /*case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE: m_s1ap_log->info("Uplink NAS: Received Authentication Response\n"); m_s1ap_log->console("Uplink NAS: Received Authentication Response\n"); handle_nas_authentication_response(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); - break; + break;*/ case LIBLTE_MME_MSG_TYPE_ATTACH_COMPLETE: m_s1ap_log->info("Uplink NAS: Received Attach Complete\n"); m_s1ap_log->console("Uplink NAS: Received Attach Complete\n"); @@ -599,7 +611,7 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, //Service request to Connected UE. //Delete ECM context and connect. m_mme_gtpc->send_delete_session_request(ecm_ctx); - //pack_context_release_request(); + //m_s1ap send_context_release_request(ecm_ctx, reply_buffer); } else { From 82b3e5e380e538b4ce73a1bc0a161799019c6fab Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 16 Feb 2018 19:08:04 +0000 Subject: [PATCH 098/342] Integrity protection of GUTI attach OK. Attach complete not yet sent. --- srsepc/src/mme/s1ap.cc | 2 +- srsepc/src/mme/s1ap_nas_transport.cc | 55 ++++++++++++++-------------- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index f72eb9bc4..ef335d533 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -517,7 +517,7 @@ s1ap::allocate_m_tmsi(uint64_t imsi) { uint32_t m_tmsi = m_next_m_tmsi++; m_tmsi_to_imsi.insert(std::pair(m_tmsi,imsi)); - m_s1ap_log->debug("Allocated M-TMSI 0x%x to IMSI %015ul,\n",m_tmsi,imsi); + m_s1ap_log->debug("Allocated M-TMSI 0x%x to IMSI %015lu,\n",m_tmsi,imsi); //uint32_t m_tmsi = 0x0123; return m_tmsi; } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 8dd6c6e68..9c445878f 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -80,11 +80,6 @@ bool s1ap_nas_transport::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) { - //LIBLTE_MME_SERVICE_REQUEST_MSG_STRUCT service_req; - - m_s1ap_log->console("Received Initial UE Message.\n"); - m_s1ap_log->info("Received Initial UE Message.\n"); - //Get info from initial UE message uint32_t enb_ue_s1ap_id = init_ue->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID; @@ -101,6 +96,8 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &pd, &msg_type); if(msg_type == LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST) { + m_s1ap_log->info("Received Attach Request \n"); + m_s1ap_log->console("Received Attach Request \n"); handle_nas_attach_request(enb_ue_s1ap_id, nas_msg, reply_buffer,reply_flag, enb_sri); } else if(msg_type == LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST) @@ -118,6 +115,11 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA handle_nas_service_request(ntohl(*m_tmsi), nas_msg, reply_buffer,reply_flag, enb_sri); return false; } + else + { + m_s1ap_log->info("Unhandled Initial UE Message 0x%x\n",msg_type); + m_s1ap_log->console("Unhandled Initial UE Message 0x%x \n", msg_type); + } m_pool->deallocate(nas_msg); return true; @@ -238,11 +240,6 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA return false; } switch (msg_type) { - /*case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE: - m_s1ap_log->info("Uplink NAS: Received Authentication Response\n"); - m_s1ap_log->console("Uplink NAS: Received Authentication Response\n"); - handle_nas_authentication_response(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); - break;*/ case LIBLTE_MME_MSG_TYPE_ATTACH_COMPLETE: m_s1ap_log->info("Uplink NAS: Received Attach Complete\n"); m_s1ap_log->console("Uplink NAS: Received Attach Complete\n"); @@ -258,8 +255,8 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA handle_tracking_area_update_request(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); 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 ); + m_s1ap_log->warning("Unhandled NAS integrity protected message 0x%x\n", msg_type ); + m_s1ap_log->console("Unhandled NAS integrity protected message 0x%x\n", msg_type ); m_pool->deallocate(nas_msg); return false; } @@ -311,33 +308,17 @@ s1ap_nas_transport::handle_nas_attach_request(uint32_t enb_ue_s1ap_id, return false; } - //Parse the message security header - uint8 pd = 0; - uint8 msg_type = 0; - uint8 sec_hdr_type = 0; - liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &pd, &sec_hdr_type); - //Get attach type from attach request if(attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI) { m_s1ap_log->console("Attach Request -- IMSI-style attach request\n"); m_s1ap_log->info("Attach Request -- IMSI-style attach request\n"); - /*if(sec_hdr_type != LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS) - { - m_s1ap_log->error("Attach request -- IMSI-stlye attach request is not plain NAS\n"); - return false; - }*/ handle_nas_imsi_attach_request(enb_ue_s1ap_id, attach_req, pdn_con_req, reply_buffer, reply_flag, enb_sri); } else if(attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI) { m_s1ap_log->console("Attach Request -- GUTI-style attach request\n"); m_s1ap_log->info("Attach Request -- GUTI-style attach request\n"); - if(sec_hdr_type != LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY) - { - m_s1ap_log->error("Attach request -- GUTI-stlye attach request is not integrity protected\n"); - return false; - } handle_nas_guti_attach_request(enb_ue_s1ap_id, attach_req, pdn_con_req, nas_msg, reply_buffer, reply_flag, enb_sri); } else @@ -462,6 +443,23 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, bool* reply_flag, struct sctp_sndrcvinfo *enb_sri) { + //Parse the message security header + uint8 pd = 0; + uint8 sec_hdr_type = 0; + liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &pd, &sec_hdr_type); + + bool integrity_valid = false; + if(sec_hdr_type != LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY) + { + m_s1ap_log->info("Attach request -- GUTI-stlye attach request is not integrity protected\n"); + m_s1ap_log->console("Attach request -- GUTI-stlye attach request is not integrity protected\n"); + } + else{ + m_s1ap_log->info("Attach request -- GUTI-stlye attach request is integrity protected\n"); + m_s1ap_log->console("Attach request -- GUTI-stlye attach request is integrity protected\n"); + } + + //GUTI style attach uint32_t m_tmsi = attach_req.eps_mobile_id.guti.m_tmsi; std::map::iterator it = m_s1ap->m_tmsi_to_imsi.find(m_tmsi); @@ -541,6 +539,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, m_s1ap_log->console("Found UE context. IMSI: %015lu\n",ue_emm_ctx->imsi); //Check NAS integrity bool msg_valid = false; + ue_emm_ctx->security_ctxt.ul_nas_count++; msg_valid = integrity_check(ue_emm_ctx,nas_msg); if(msg_valid == true) { From c5ffdfe8c74bf3d06f393783c6e1847888bc791e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 16 Feb 2018 21:31:11 +0100 Subject: [PATCH 099/342] set byte_buffer ptr to null after deallocating from pool --- lib/include/srslte/common/buffer_pool.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index a4186a78b..e48144b6f 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -164,6 +164,7 @@ public: } b->reset(); pool->deallocate(b); + b = NULL; } private: buffer_pool *pool; From 1be93d4682baa5e2a166ebc940f894e68354ac16 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 16 Feb 2018 21:32:21 +0100 Subject: [PATCH 100/342] add RLC UM destructor --- lib/include/srslte/upper/rlc_um.h | 1 + lib/src/upper/rlc_um.cc | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/include/srslte/upper/rlc_um.h b/lib/include/srslte/upper/rlc_um.h index 0a2469a7c..6d8eb6d08 100644 --- a/lib/include/srslte/upper/rlc_um.h +++ b/lib/include/srslte/upper/rlc_um.h @@ -50,6 +50,7 @@ class rlc_um { public: rlc_um(); + ~rlc_um(); void init(log *rlc_entity_log_, uint32_t lcid_, diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 213e8c840..a365a4501 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -59,6 +59,11 @@ rlc_um::rlc_um() : tx_sdu_queue(16) pdu_lost = false; } +rlc_um::~rlc_um() +{ + stop(); +} + void rlc_um::init(srslte::log *log_, uint32_t lcid_, srsue::pdcp_interface_rlc *pdcp_, @@ -114,12 +119,13 @@ void rlc_um::empty_queue() { void rlc_um::stop() { reset(); - mac_timers->timer_release_id(reordering_timer_id); + if (mac_timers) { + mac_timers->timer_release_id(reordering_timer_id); + } } void rlc_um::reset() { - // Empty tx_sdu_queue before locking the mutex empty_queue(); @@ -129,12 +135,17 @@ void rlc_um::reset() vr_ux = 0; vr_uh = 0; pdu_lost = false; - if(rx_sdu) - rx_sdu->reset(); - if(tx_sdu) - tx_sdu->reset(); - if(mac_timers) + if(rx_sdu) { + pool->deallocate(rx_sdu); + } + + if(tx_sdu) { + pool->deallocate(tx_sdu); + } + + if(mac_timers) { reordering_timer->stop(); + } // Drop all messages in RX window std::map::iterator it; From a6ccb05bb107bb91a2eeeb95b00c384d1d627968 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 16 Feb 2018 21:32:53 +0100 Subject: [PATCH 101/342] fix mem leak in RLC UM test and RLC AM stress tester --- lib/test/upper/rlc_am_stress_test.cc | 1 + lib/test/upper/rlc_um_test.cc | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/lib/test/upper/rlc_am_stress_test.cc b/lib/test/upper/rlc_am_stress_test.cc index 086a41bd8..137236b4a 100644 --- a/lib/test/upper/rlc_am_stress_test.cc +++ b/lib/test/upper/rlc_am_stress_test.cc @@ -85,6 +85,7 @@ private: usleep(100); } running = false; + byte_buffer_pool::get_instance()->deallocate(pdu); } rlc_interface_mac *rlc1; diff --git a/lib/test/upper/rlc_um_test.cc b/lib/test/upper/rlc_um_test.cc index 6ce39ef7f..3755c1174 100644 --- a/lib/test/upper/rlc_um_test.cc +++ b/lib/test/upper/rlc_um_test.cc @@ -62,6 +62,14 @@ public: n_sdus = 0; } + ~rlc_um_tester(){ + for (uint32_t i = 0; i < NBUFS; i++) { + if (sdus[i] != NULL) { + byte_buffer_pool::get_instance()->deallocate(sdus[i]); + } + } + } + // PDCP interface void write_pdu(uint32_t lcid, byte_buffer_t *sdu) { From f8303acba7b6131b1d057efa164ce5876af3033f Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sat, 17 Feb 2018 21:37:48 +0100 Subject: [PATCH 102/342] Fixed memory leak in logger_stdout --- lib/include/srslte/common/logger_stdout.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/include/srslte/common/logger_stdout.h b/lib/include/srslte/common/logger_stdout.h index 00e4ffa7a..b76faadaf 100644 --- a/lib/include/srslte/common/logger_stdout.h +++ b/lib/include/srslte/common/logger_stdout.h @@ -42,7 +42,10 @@ namespace srslte { { public: void log(std::string *msg) { - fprintf(stdout, "%s", msg->c_str()); + if (msg) { + fprintf(stdout, "%s", msg->c_str()); + delete msg; + } } }; From 4ee08fdecaafb33a65dedfbda440003e99a04a64 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 19 Feb 2018 15:19:07 +0000 Subject: [PATCH 103/342] Changing send initial context setup request to not need the create session response struct. --- srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h | 4 +- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 84 ++++++++++++--------------- srsepc/src/mme/s1ap_nas_transport.cc | 30 ++++++++-- 3 files changed, 67 insertions(+), 51 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h index 9979b6594..3e4136141 100644 --- a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h @@ -47,7 +47,9 @@ public: void init(void); - bool send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte::gtpc_create_session_response *cs_resp, struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid); + //bool send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte::gtpc_create_session_response *cs_resp, struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid); + bool send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, ue_ecm_ctx_t *ecm_ctx, uint16_t erab_id, + struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid, struct srslte::gtpc_f_teid_ie sgw_s1u_fteid, struct srslte::gtpc_pdn_address_allocation_ie pdn_addr_aloc); bool handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *in_ctxt_resp); bool handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ue_rel, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); bool send_ue_context_release_command(ue_ecm_ctx_t *ecm_ctx, srslte::byte_buffer_t *reply_buffer); diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index ba9d38577..6d645c095 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -77,7 +77,12 @@ s1ap_ctx_mngmt_proc::init(void) } bool -s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte::gtpc_create_session_response *cs_resp, struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid) +s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, + ue_ecm_ctx_t *ecm_ctx, + uint16_t erab_id, + struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid, + struct srslte::gtpc_f_teid_ie sgw_s1u_fteid, + struct srslte::gtpc_pdn_address_allocation_ie pdn_addr_alloc) { int s1mme = m_s1ap->get_s1_mme(); @@ -97,23 +102,9 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, m_s1ap_log->info("Preparing to send Initial Context Setup request\n"); - //Find UE Context - ue_ecm_ctx_t *ue_ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); - if(ue_ecm_ctx == NULL) - { - m_s1ap_log->error("Could not find UE to send Setup Context Request. MME S1AP Id: %d", mme_ue_s1ap_id); - return false; - } - ue_emm_ctx_t *ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); - if(ue_emm_ctx == NULL) - { - m_s1ap_log->error("Could not find UE to send Setup Context Request. MME S1AP Id: %d", mme_ue_s1ap_id); - return false; - } - //Add MME and eNB S1AP Ids - in_ctxt_req->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ecm_ctx->mme_ue_s1ap_id; - in_ctxt_req->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ecm_ctx->enb_ue_s1ap_id; + in_ctxt_req->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ecm_ctx->mme_ue_s1ap_id; + in_ctxt_req->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ecm_ctx->enb_ue_s1ap_id; //Set UE-AMBR in_ctxt_req->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateDL.BitRate=1000000000; @@ -121,7 +112,7 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, //Setup eRAB context in_ctxt_req->E_RABToBeSetupListCtxtSUReq.len = 1; - erab_ctxt->e_RAB_ID.E_RAB_ID = cs_resp->eps_bearer_context_created.ebi; + erab_ctxt->e_RAB_ID.E_RAB_ID = erab_id; //Setup E-RAB QoS parameters erab_ctxt->e_RABlevelQoSParameters.qCI.QCI = 9; erab_ctxt->e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel.PriorityLevel = 15 ;//Lowest @@ -131,25 +122,25 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, erab_ctxt->e_RABlevelQoSParameters.gbrQosInformation_present=false; //Set E-RAB S-GW F-TEID - if (cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid_present == false){ - m_s1ap_log->error("Did not receive S1-U TEID in create session response\n"); - return false; - } + //if (cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid_present == false){ + // m_s1ap_log->error("Did not receive S1-U TEID in create session response\n"); + // return false; + //} erab_ctxt->transportLayerAddress.n_bits = 32; //IPv4 - uint32_t sgw_s1u_ip = htonl(cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.ipv4); + uint32_t sgw_s1u_ip = htonl(sgw_s1u_fteid.ipv4); //uint32_t sgw_s1u_ip = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.ipv4; uint8_t *tmp_ptr = erab_ctxt->transportLayerAddress.buffer; liblte_value_2_bits(sgw_s1u_ip, &tmp_ptr, 32);//FIXME consider ipv6 - uint32_t tmp_teid = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.teid; - memcpy(erab_ctxt->gTP_TEID.buffer, &tmp_teid, sizeof(uint32_t)); + uint32_t sgw_s1u_teid = sgw_s1u_fteid.teid; + memcpy(erab_ctxt->gTP_TEID.buffer, &sgw_s1u_teid, sizeof(uint32_t)); //Set UE security capabilities and k_enb bzero(in_ctxt_req->UESecurityCapabilities.encryptionAlgorithms.buffer,sizeof(uint8_t)*16); bzero(in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer,sizeof(uint8_t)*16); for(int i = 0; i<3; i++) { - if(ue_emm_ctx->security_ctxt.ue_network_cap.eea[i+1] == true) + if(emm_ctx->security_ctxt.ue_network_cap.eea[i+1] == true) { in_ctxt_req->UESecurityCapabilities.encryptionAlgorithms.buffer[i] = 1; //EEA supported } @@ -157,7 +148,7 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, { in_ctxt_req->UESecurityCapabilities.encryptionAlgorithms.buffer[i] = 0; //EEA not supported } - if(ue_emm_ctx->security_ctxt.ue_network_cap.eia[i+1] == true) + if(emm_ctx->security_ctxt.ue_network_cap.eia[i+1] == true) { in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer[i] = 1; //EEA supported } @@ -168,21 +159,22 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, // in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer[0] = 1; //EIA1 } //Get K eNB - liblte_unpack(ue_emm_ctx->security_ctxt.k_enb, 32, in_ctxt_req->SecurityKey.buffer); - m_s1ap_log->info_hex(ue_emm_ctx->security_ctxt.k_enb, 32, "Initial Context Setup Request -- Key eNB\n"); + liblte_unpack(emm_ctx->security_ctxt.k_enb, 32, in_ctxt_req->SecurityKey.buffer); + m_s1ap_log->info_hex(emm_ctx->security_ctxt.k_enb, 32, "Initial Context Setup Request -- Key eNB\n"); + //Set Attach accepted and activat default bearer NAS messages - if(cs_resp->paa_present != true) - { - m_s1ap_log->error("PAA not present\n"); - return false; - } - if(cs_resp->paa.pdn_type != srslte::GTPC_PDN_TYPE_IPV4) - { - m_s1ap_log->error("IPv6 not supported yet\n"); - return false; - } + //if(cs_resp->paa_present != true) + //{ + // m_s1ap_log->error("PDN Adress Allocation not present\n"); + // return false; + //} + //if(cs_resp->paa.pdn_type != srslte::GTPC_PDN_TYPE_IPV4) + //{ + // m_s1ap_log->error("IPv6 not supported yet\n"); + // return false; + //} srslte::byte_buffer_t *nas_buffer = m_pool->allocate(); - m_s1ap_nas_transport->pack_attach_accept(ue_emm_ctx, ue_ecm_ctx, erab_ctxt, &cs_resp->paa, nas_buffer); + m_s1ap_nas_transport->pack_attach_accept(emm_ctx, ecm_ctx, erab_ctxt, &pdn_addr_alloc, nas_buffer); LIBLTE_ERROR_ENUM err = liblte_s1ap_pack_s1ap_pdu(&pdu, (LIBLTE_BYTE_MSG_STRUCT*)reply_buffer); @@ -192,7 +184,7 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, return false; } //Send Reply to eNB - ssize_t n_sent = sctp_send(s1mme,reply_buffer->msg, reply_buffer->N_bytes, &ue_ecm_ctx->enb_sri, 0); + ssize_t n_sent = sctp_send(s1mme,reply_buffer->msg, reply_buffer->N_bytes, &ecm_ctx->enb_sri, 0); if(n_sent == -1) { m_s1ap_log->error("Failed to send Initial Context Setup Request\n"); @@ -200,16 +192,16 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, } //Change E-RAB state to Context Setup Requested and save S-GW control F-TEID - ue_ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].state = ERAB_CTX_REQUESTED; - ue_ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.teid = sgw_ctrl_fteid.teid; - ue_ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.ipv4 = sgw_ctrl_fteid.ipv4; + ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].state = ERAB_CTX_REQUESTED; + ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.teid = sgw_ctrl_fteid.teid; + ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.ipv4 = sgw_ctrl_fteid.ipv4; struct in_addr addr; addr.s_addr = htonl(sgw_s1u_ip); m_s1ap_log->info("Sent Intial Context Setup Request. E-RAB id %d \n",erab_ctxt->e_RAB_ID.E_RAB_ID); - m_s1ap_log->info("Initial Context -- S1-U TEID 0x%x. IP %s \n", tmp_teid,inet_ntoa(addr)); + m_s1ap_log->info("Initial Context -- S1-U TEID 0x%x. IP %s \n", sgw_s1u_teid,inet_ntoa(addr)); m_s1ap_log->console("Sent Intial Context Setup Request, E-RAB id %d\n",erab_ctxt->e_RAB_ID.E_RAB_ID); - m_s1ap_log->console("Initial Context -- S1-U TEID 0x%x. IP %s \n", tmp_teid,inet_ntoa(addr)); + m_s1ap_log->console("Initial Context -- S1-U TEID 0x%x. IP %s \n", sgw_s1u_teid,inet_ntoa(addr)); m_pool->deallocate(reply_buffer); m_pool->deallocate(nas_buffer); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 9c445878f..99cbc52f5 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -378,7 +378,6 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, //Save whether secure ESM information transfer is necessary ue_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; - //Add eNB info to UE ctxt //Initialize E-RABs for(uint i = 0 ; i< MAX_ERABS_PER_UE; i++) { @@ -543,6 +542,28 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, msg_valid = integrity_check(ue_emm_ctx,nas_msg); if(msg_valid == true) { + //Create new MME UE S1AP Identity + ue_emm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + + //Create UE ECM context + ue_ecm_ctx_t ue_ecm_ctx; + + //Set UE ECM context + ue_ecm_ctx.imsi = ue_emm_ctx->imsi; + ue_ecm_ctx.mme_ue_s1ap_id = ue_emm_ctx->mme_ue_s1ap_id; + //Set eNB information + ue_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; + memcpy(&ue_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + //Save whether secure ESM information transfer is necessary + ue_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; + + //Initialize E-RABs + for(uint i = 0 ; i< MAX_ERABS_PER_UE; i++) + { + ue_ecm_ctx.erabs_ctx[i].state = ERAB_DEACTIVATED; + ue_ecm_ctx.erabs_ctx[i].erab_id = i; + } + m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); //Create session request m_s1ap_log->console("GUTI Attach -- NAS Integrity OK."); m_mme_gtpc->send_create_session_request(ue_emm_ctx->imsi, ue_emm_ctx->mme_ue_s1ap_id); @@ -608,9 +629,10 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, if(ecm_ctx !=NULL) { //Service request to Connected UE. - //Delete ECM context and connect. - m_mme_gtpc->send_delete_session_request(ecm_ctx); - //m_s1ap send_context_release_request(ecm_ctx, reply_buffer); + //Delete eNB context and connect. + + m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); + m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ecm_ctx); } else { From fc0f1e4c23407546dbff1af46dfe8abda8890b22 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 19 Feb 2018 17:54:01 +0000 Subject: [PATCH 104/342] Sendind intial context setup in response to service request. --- srsepc/hdr/mme/s1ap_common.h | 2 + srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h | 3 +- srsepc/src/mme/mme_gtpc.cc | 42 ++++++++++++++++++++- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 53 ++++++++++----------------- srsepc/src/mme/s1ap_nas_transport.cc | 8 +++- 5 files changed, 69 insertions(+), 39 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index 8bb6944ff..c69eb05d1 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -126,6 +126,8 @@ typedef struct{ uint8_t erab_id; srslte::gtpc_f_teid_ie enb_fteid; srslte::gtpc_f_teid_ie sgw_ctrl_fteid; + srslte::gtpc_f_teid_ie sgw_s1u_fteid; + srslte::gtpc_pdn_address_allocation_ie pdn_addr_alloc; } erab_ctx_t; typedef struct{ diff --git a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h index 3e4136141..44458aea6 100644 --- a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h @@ -48,8 +48,7 @@ public: void init(void); //bool send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte::gtpc_create_session_response *cs_resp, struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid); - bool send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, ue_ecm_ctx_t *ecm_ctx, uint16_t erab_id, - struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid, struct srslte::gtpc_f_teid_ie sgw_s1u_fteid, struct srslte::gtpc_pdn_address_allocation_ie pdn_addr_aloc); + bool send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, ue_ecm_ctx_t *ecm_ctx, erab_ctx_t *erab_ctx); bool handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *in_ctxt_resp); bool handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ue_rel, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); bool send_ue_context_release_command(ue_ecm_ctx_t *ecm_ctx, srslte::byte_buffer_t *reply_buffer); diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 6f4a1cdcc..e6f4511df 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -162,11 +162,51 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu) sgw_ctrl_fteid.teid = cs_resp_pdu->header.teid; sgw_ctrl_fteid.ipv4 = 0; //FIXME This is not used for now. In the future it will be obtained from the socket addr_info + //Get S-GW S1-u F-TEID + if (cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid_present == false){ + m_mme_gtpc_log->error("Did not receive SGW S1-U F-TEID in create session response\n"); + return; + } m_mme_gtpc_log->console("Create Session Response -- SPGW control TEID %d\n", sgw_ctrl_fteid.teid); in_addr s1u_addr; s1u_addr.s_addr = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.ipv4; m_mme_gtpc_log->console("Create Session Response -- SPGW S1-U Address: %s\n", inet_ntoa(s1u_addr)); - m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(mme_s1ap_id, cs_resp, sgw_ctrl_fteid); + + //Check UE Ipv4 address was allocated + if(cs_resp->paa_present != true) + { + m_mme_gtpc_log->error("PDN Adress Allocation not present\n"); + return; + } + if(cs_resp->paa.pdn_type != srslte::GTPC_PDN_TYPE_IPV4) + { + m_mme_gtpc_log->error("IPv6 not supported yet\n"); + return; + } + + //Save create session response info to E-RAB context + ue_ecm_ctx_t *ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_s1ap_id); + if(ecm_ctx ==NULL) + { + m_mme_gtpc_log->error("Could not find UE ECM context\n"); + return; + } + ue_emm_ctx_t *emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ecm_ctx->imsi); + if(emm_ctx ==NULL) + { + m_mme_gtpc_log->error("Could not find UE EMM context\n"); + return; + } + + //Set EPS bearer context + //FIXME default EPS bearer is hard-coded + int default_bearer=5; + erab_ctx_t *erab_ctx = &ecm_ctx->erabs_ctx[default_bearer]; + erab_ctx->pdn_addr_alloc= cs_resp->paa; + erab_ctx->sgw_ctrl_fteid = sgw_ctrl_fteid; + erab_ctx->sgw_s1u_fteid = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid; + + m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, erab_ctx); } diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 6d645c095..c68301ff0 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -79,10 +79,7 @@ s1ap_ctx_mngmt_proc::init(void) bool s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, ue_ecm_ctx_t *ecm_ctx, - uint16_t erab_id, - struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid, - struct srslte::gtpc_f_teid_ie sgw_s1u_fteid, - struct srslte::gtpc_pdn_address_allocation_ie pdn_addr_alloc) + erab_ctx_t *erab_ctx) { int s1mme = m_s1ap->get_s1_mme(); @@ -97,7 +94,7 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *in_ctxt_req = &init->choice.InitialContextSetupRequest; - LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *erab_ctxt = &in_ctxt_req->E_RABToBeSetupListCtxtSUReq.buffer[0]; //FIXME support more than one erab + LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *erab_ctx_req = &in_ctxt_req->E_RABToBeSetupListCtxtSUReq.buffer[0]; //FIXME support more than one erab srslte::byte_buffer_t *reply_buffer = m_pool->allocate(); m_s1ap_log->info("Preparing to send Initial Context Setup request\n"); @@ -112,28 +109,28 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, //Setup eRAB context in_ctxt_req->E_RABToBeSetupListCtxtSUReq.len = 1; - erab_ctxt->e_RAB_ID.E_RAB_ID = erab_id; + erab_ctx_req->e_RAB_ID.E_RAB_ID = erab_ctx->erab_id; //Setup E-RAB QoS parameters - erab_ctxt->e_RABlevelQoSParameters.qCI.QCI = 9; - erab_ctxt->e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel.PriorityLevel = 15 ;//Lowest - erab_ctxt->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionCapability = LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_SHALL_NOT_TRIGGER_PRE_EMPTION; - erab_ctxt->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability = LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_PRE_EMPTABLE; + erab_ctx_req->e_RABlevelQoSParameters.qCI.QCI = 9; + erab_ctx_req->e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel.PriorityLevel = 15 ;//Lowest + erab_ctx_req->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionCapability = LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_SHALL_NOT_TRIGGER_PRE_EMPTION; + erab_ctx_req->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability = LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_PRE_EMPTABLE; - erab_ctxt->e_RABlevelQoSParameters.gbrQosInformation_present=false; + erab_ctx_req->e_RABlevelQoSParameters.gbrQosInformation_present=false; //Set E-RAB S-GW F-TEID //if (cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid_present == false){ // m_s1ap_log->error("Did not receive S1-U TEID in create session response\n"); // return false; //} - erab_ctxt->transportLayerAddress.n_bits = 32; //IPv4 - uint32_t sgw_s1u_ip = htonl(sgw_s1u_fteid.ipv4); + erab_ctx_req->transportLayerAddress.n_bits = 32; //IPv4 + uint32_t sgw_s1u_ip = htonl(erab_ctx->sgw_s1u_fteid.ipv4); //uint32_t sgw_s1u_ip = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.ipv4; - uint8_t *tmp_ptr = erab_ctxt->transportLayerAddress.buffer; + uint8_t *tmp_ptr = erab_ctx_req->transportLayerAddress.buffer; liblte_value_2_bits(sgw_s1u_ip, &tmp_ptr, 32);//FIXME consider ipv6 - uint32_t sgw_s1u_teid = sgw_s1u_fteid.teid; - memcpy(erab_ctxt->gTP_TEID.buffer, &sgw_s1u_teid, sizeof(uint32_t)); + uint32_t sgw_s1u_teid = erab_ctx->sgw_s1u_fteid.teid; + memcpy(erab_ctx_req->gTP_TEID.buffer, &sgw_s1u_teid, sizeof(uint32_t)); //Set UE security capabilities and k_enb bzero(in_ctxt_req->UESecurityCapabilities.encryptionAlgorithms.buffer,sizeof(uint8_t)*16); @@ -156,25 +153,13 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, { in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer[i] = 0; //EEA not supported } - // in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer[0] = 1; //EIA1 } //Get K eNB liblte_unpack(emm_ctx->security_ctxt.k_enb, 32, in_ctxt_req->SecurityKey.buffer); m_s1ap_log->info_hex(emm_ctx->security_ctxt.k_enb, 32, "Initial Context Setup Request -- Key eNB\n"); - //Set Attach accepted and activat default bearer NAS messages - //if(cs_resp->paa_present != true) - //{ - // m_s1ap_log->error("PDN Adress Allocation not present\n"); - // return false; - //} - //if(cs_resp->paa.pdn_type != srslte::GTPC_PDN_TYPE_IPV4) - //{ - // m_s1ap_log->error("IPv6 not supported yet\n"); - // return false; - //} srslte::byte_buffer_t *nas_buffer = m_pool->allocate(); - m_s1ap_nas_transport->pack_attach_accept(emm_ctx, ecm_ctx, erab_ctxt, &pdn_addr_alloc, nas_buffer); + m_s1ap_nas_transport->pack_attach_accept(emm_ctx, ecm_ctx, erab_ctx_req, &erab_ctx->pdn_addr_alloc, nas_buffer); LIBLTE_ERROR_ENUM err = liblte_s1ap_pack_s1ap_pdu(&pdu, (LIBLTE_BYTE_MSG_STRUCT*)reply_buffer); @@ -192,15 +177,15 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, } //Change E-RAB state to Context Setup Requested and save S-GW control F-TEID - ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].state = ERAB_CTX_REQUESTED; - ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.teid = sgw_ctrl_fteid.teid; - ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.ipv4 = sgw_ctrl_fteid.ipv4; + ecm_ctx->erabs_ctx[erab_ctx_req->e_RAB_ID.E_RAB_ID].state = ERAB_CTX_REQUESTED; + //ecm_ctx->erabs_ctx[erab_ctx_req->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.teid = sgw_ctrl_fteid.teid; + //ecm_ctx->erabs_ctx[erab_ctx_req->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.ipv4 = sgw_ctrl_fteid.ipv4; struct in_addr addr; addr.s_addr = htonl(sgw_s1u_ip); - m_s1ap_log->info("Sent Intial Context Setup Request. E-RAB id %d \n",erab_ctxt->e_RAB_ID.E_RAB_ID); + m_s1ap_log->info("Sent Intial Context Setup Request. E-RAB id %d \n",erab_ctx_req->e_RAB_ID.E_RAB_ID); m_s1ap_log->info("Initial Context -- S1-U TEID 0x%x. IP %s \n", sgw_s1u_teid,inet_ntoa(addr)); - m_s1ap_log->console("Sent Intial Context Setup Request, E-RAB id %d\n",erab_ctxt->e_RAB_ID.E_RAB_ID); + m_s1ap_log->console("Sent Intial Context Setup Request, E-RAB id %d\n",erab_ctx_req->e_RAB_ID.E_RAB_ID); m_s1ap_log->console("Initial Context -- S1-U TEID 0x%x. IP %s \n", sgw_s1u_teid,inet_ntoa(addr)); m_pool->deallocate(reply_buffer); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 99cbc52f5..acf30c422 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -630,13 +630,17 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, { //Service request to Connected UE. //Delete eNB context and connect. - + m_s1ap_log->console("Service Request -- User has ECM context already\n"); + m_s1ap_log->info("Service Request -- User has ECM context already\n"); m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); - m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ecm_ctx); + int default_bearer_id = 5; + m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ue_emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[default_bearer_id]); } else { //UE not connect. Connect normally. + m_s1ap_log->console("Service Request -- User without ECM context\n"); + m_s1ap_log->info("Service Request -- User without ECM context\n"); } } else From c02b67b709067a0e418fff095bcdf0a2fe0ef1a7 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 19 Feb 2018 19:28:54 +0000 Subject: [PATCH 105/342] Sending initial context setup request on receiving service request --- srsepc/hdr/mme/s1ap_nas_transport.h | 1 + srsepc/src/mme/s1ap_nas_transport.cc | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index c36081ae2..7cc692a4e 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -66,6 +66,7 @@ public: bool* reply_flag, struct sctp_sndrcvinfo *enb_sri); bool handle_nas_service_request(uint32_t m_tmsi, + uint32_t enb_ue_s1ap_id, srslte::byte_buffer_t *nas_msg, srslte::byte_buffer_t *reply_buffer, bool* reply_flag, diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index acf30c422..3abc81768 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -110,9 +110,12 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA m_s1ap_log->console("Service request -- S-TMSI not present\n" ); } uint32_t *m_tmsi = (uint32_t*) &init_ue->S_TMSI.m_TMSI.buffer; + uint32_t enb_ue_s1ap_id = init_ue->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID; m_s1ap_log->info("Service request -- S-TMSI 0x%x\n ", ntohl(*m_tmsi)); m_s1ap_log->console("Service request -- S-TMSI 0x%x\n", ntohl(*m_tmsi) ); - handle_nas_service_request(ntohl(*m_tmsi), nas_msg, reply_buffer,reply_flag, enb_sri); + m_s1ap_log->info("Service request -- eNB UE S1AP Id %d\n ", enb_ue_s1ap_id); + m_s1ap_log->console("Service request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); + handle_nas_service_request(ntohl(*m_tmsi), enb_ue_s1ap_id, nas_msg, reply_buffer,reply_flag, enb_sri); return false; } else @@ -586,6 +589,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, bool s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, + uint32_t enb_ue_s1ap_id, srslte::byte_buffer_t *nas_msg, srslte::byte_buffer_t *reply_buffer, bool* reply_flag, @@ -629,6 +633,11 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, if(ecm_ctx !=NULL) { //Service request to Connected UE. + //Set eNB UE S1ap identity + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + m_s1ap_log->console("Service Request -- eNB UE S1AP Id %d \n", enb_ue_s1ap_id); + m_s1ap_log->info("Service Request -- eNB UE S1AP Id %d\n ", enb_ue_s1ap_id); + //Delete eNB context and connect. m_s1ap_log->console("Service Request -- User has ECM context already\n"); m_s1ap_log->info("Service Request -- User has ECM context already\n"); From 5f4613bffdf141d172e44ea195dda9321ae77593 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 19 Feb 2018 20:09:09 +0000 Subject: [PATCH 106/342] Fixing conflicts from merge. --- srsepc/hdr/mme/s1ap_nas_transport.h | 2 ++ srsepc/src/mme/s1ap_nas_transport.cc | 29 ++++++++++++++++------------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index 59375dbcd..b8eb98805 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -79,6 +79,8 @@ public: bool handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag); bool handle_tracking_area_update_request(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag); + bool handle_authentication_failure(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); + bool integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_buffer_t *pdu); bool short_integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_buffer_t *pdu); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 281364bf4..fa0da0d2c 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -259,8 +259,7 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA 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++; + handle_authentication_failure(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); break; default: m_s1ap_log->warning("Unhandled NAS integrity protected message 0x%x\n", msg_type ); @@ -929,10 +928,10 @@ s1ap_nas_transport::handle_tracking_area_update_request(srslte::byte_buffer_t *n 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); - /* + LIBLTE_MME_TRACKING_AREA_UPDATE_ACCEPT_MSG_STRUCT tau_acc; - + /* bool t3412_present; bool guti_present; bool tai_list_present; @@ -1104,7 +1103,7 @@ s1ap_nas_transport::integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_buffer_t 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) +s1ap_nas_transport::handle_authentication_failure(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) { uint8_t autn[16]; uint8_t rand[16]; @@ -1117,6 +1116,12 @@ s1ap_nas_transport::handle_authentication_failure(srslte::byte_buffer_t *nas_msg return false; } + ue_emm_ctx_t *emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); + if(emm_ctx == NULL) + { + m_s1ap_log->error("Could not find UE EMM context\n"); + return false; + } switch(auth_fail.emm_cause){ case 20: @@ -1134,22 +1139,22 @@ s1ap_nas_transport::handle_authentication_failure(srslte::byte_buffer_t *nas_msg m_s1ap_log->error("Missing fail parameter\n"); return false; } - if(!m_hss->resync_sqn(ue_ctx->imsi, auth_fail.auth_fail_param)) + if(!m_hss->resync_sqn(ue_ecm_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); + m_s1ap_log->console("Resynchronization failed. IMSI %015lu\n", ue_ecm_ctx->imsi); + m_s1ap_log->info("Resynchronization failed. IMSI %015lu\n", ue_ecm_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)) + if(!m_hss->gen_auth_info_answer(ue_ecm_ctx->imsi, emm_ctx->security_ctxt.k_asme, autn, rand, emm_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); + m_s1ap_log->console("User not found. IMSI %015lu\n", ue_ecm_ctx->imsi); + m_s1ap_log->info("User not found. IMSI %015lu\n", ue_ecm_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); + pack_authentication_request(reply_msg, ue_ecm_ctx->enb_ue_s1ap_id, ue_ecm_ctx->mme_ue_s1ap_id, autn, rand); //Send reply to eNB *reply_flag = true; From 0389338fe3c8ed0a30c430f7e47c0b3d46b8e5a5 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 19 Feb 2018 20:54:43 +0000 Subject: [PATCH 107/342] whitespace change --- 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 fa0da0d2c..96834c3ba 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -1163,7 +1163,7 @@ s1ap_nas_transport::handle_authentication_failure(srslte::byte_buffer_t *nas_msg //TODO Start T3460 Timer! break; - } + } return true; } From d959608e10373c83fa4a6284448425cfccf71459 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 20 Feb 2018 11:44:46 +0100 Subject: [PATCH 108/342] fix mem dealloc in viterbi for 16bit AVX --- lib/src/phy/fec/viterbi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/src/phy/fec/viterbi.c b/lib/src/phy/fec/viterbi.c index 25d77ef36..4e5801b94 100644 --- a/lib/src/phy/fec/viterbi.c +++ b/lib/src/phy/fec/viterbi.c @@ -166,9 +166,15 @@ void free37_avx2_16bit(void *o) { if (q->symbols_uc) { free(q->symbols_uc); } + if (q->symbols_us) { + free(q->symbols_us); + } if (q->tmp) { free(q->tmp); } + if (q->tmp_s) { + free(q->tmp_s); + } delete_viterbi37_avx2_16bit(q->ptr); } From 94fe9d4a4710dc09a41bcb0e4844f59923d4fb35 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 20 Feb 2018 12:27:02 +0100 Subject: [PATCH 109/342] rlc: add basic RLC AM reset test --- lib/test/upper/rlc_am_test.cc | 57 +++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index 184de3a00..67305c093 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -1056,6 +1056,60 @@ void resegment_test_6() } } +void reset_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); + rlc_am_tester tester; + mac_dummy_timers timers; + + rlc_am rlc1; + int len; + + log1.set_level(srslte::LOG_LEVEL_DEBUG); + + rlc1.init(&log1, 1, &tester, &tester, &timers); + + 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; + + rlc1.configure(&cnfg); + + // Push 1 SDU of size 10 into RLC1 + byte_buffer_t sdu_buf; + *sdu_buf.msg = 1; // Write the index into the buffer + sdu_buf.N_bytes = 100; + rlc1.write_sdu(&sdu_buf); + + // read 1 PDU from RLC1 and force segmentation + byte_buffer_t pdu_bufs; + len = rlc1.read_pdu(pdu_bufs.msg, 4); + pdu_bufs.N_bytes = len; + + // reset RLC1 + rlc1.reset(); + + // read another PDU segment from RLC1 + len = rlc1.read_pdu(pdu_bufs.msg, 4); + pdu_bufs.N_bytes = len; + + // now empty RLC buffer + len = rlc1.read_pdu(pdu_bufs.msg, 100); + pdu_bufs.N_bytes = len; + + assert(0 == rlc1.get_buffer_state()); +} + int main(int argc, char **argv) { basic_test(); byte_buffer_pool::get_instance()->cleanup(); @@ -1086,4 +1140,7 @@ int main(int argc, char **argv) { resegment_test_6(); byte_buffer_pool::get_instance()->cleanup(); + + reset_test(); + byte_buffer_pool::get_instance()->cleanup(); } From 8d852ddfe5e4f6eedb80e247d62b8628f9643c2f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 20 Feb 2018 17:54:09 +0100 Subject: [PATCH 110/342] only reset SDU buffer in RLC AM/UM --- lib/src/upper/rlc_am.cc | 8 -------- lib/src/upper/rlc_um.cc | 4 ++-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 652970011..b34b0cb0b 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -72,14 +72,6 @@ rlc_am::~rlc_am() { // reset RLC and dealloc SDUs stop(); - - if(rx_sdu) { - pool->deallocate(rx_sdu); - } - - if(tx_sdu) { - pool->deallocate(tx_sdu); - } } void rlc_am::init(srslte::log *log_, diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index a365a4501..3fbcbaadf 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -136,11 +136,11 @@ void rlc_um::reset() vr_uh = 0; pdu_lost = false; if(rx_sdu) { - pool->deallocate(rx_sdu); + rx_sdu->reset(); } if(tx_sdu) { - pool->deallocate(tx_sdu); + tx_sdu->reset(); } if(mac_timers) { From bdc72c65c451eec5763c34b10e9df2e5dfcd9f55 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 20 Feb 2018 18:54:41 +0000 Subject: [PATCH 111/342] Adding print to debug TPC issue. --- srsepc/hdr/spgw/spgw.h | 4 ++++ srsepc/src/spgw/spgw.cc | 23 +++++++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/srsepc/hdr/spgw/spgw.h b/srsepc/hdr/spgw/spgw.h index 095b4d9b0..f39674ba7 100644 --- a/srsepc/hdr/spgw/spgw.h +++ b/srsepc/hdr/spgw/spgw.h @@ -117,6 +117,10 @@ private: uint32_t m_h_next_ue_ip; + /*Time*/ + struct timeval m_t_last_dl; + struct timeval m_t_last_ul; + /*Logs*/ srslte::log_filter *m_spgw_log; diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index add16b2c4..55f19818d 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -224,6 +224,9 @@ spgw::init_sgi_if(spgw_args_t *args) return srslte::ERROR_CANT_START; } + //Set initial time of setup + gettimeofday(&m_t_last_dl, NULL); + m_sgi_up = true; return(srslte::ERROR_NONE); } @@ -297,15 +300,11 @@ spgw::run_thread() if (FD_ISSET(m_s1u, &set)) { msg->N_bytes = recvfrom(m_s1u, msg->msg, SRSLTE_MAX_BUFFER_SIZE_BYTES, 0, &src_addr, &addrlen ); - //m_spgw_log->console("Received PDU from S1-U. Bytes %d\n", msg->N_bytes); - //m_spgw_log->debug("Received PDU from S1-U. Bytes %d\n", msg->N_bytes); handle_s1u_pdu(msg); } if (FD_ISSET(m_sgi_if, &set)) { msg->N_bytes = read(sgi, msg->msg, SRSLTE_MAX_BUFFER_SIZE_BYTES); - //m_spgw_log->console("Received PDU from SGi. Bytes %d\n", msg->N_bytes); - //m_spgw_log->debug("Received PDU from SGi. Bytes %d\n", msg->N_bytes); handle_sgi_pdu(msg); } } @@ -328,6 +327,8 @@ spgw::handle_sgi_pdu(srslte::byte_buffer_t *msg) bool ip_found = false; srslte::gtpc_f_teid_ie enb_fteid; + struct timeval t_now, t_delta; + version = msg->msg[0]>>4; ((uint8_t*)&dest_ip)[0] = msg->msg[16]; ((uint8_t*)&dest_ip)[1] = msg->msg[17]; @@ -380,8 +381,18 @@ spgw::handle_sgi_pdu(srslte::byte_buffer_t *msg) m_spgw_log->error("Error sending packet to eNB\n"); return; } - //m_spgw_log->console("Sent packet to %s:%d. Bytes=%d/%d\n",inet_ntoa(enb_addr.sin_addr), GTPU_RX_PORT,n,msg->N_bytes); - + else if((unsigned int) n!=msg->N_bytes) + { + m_spgw_log->error("Mis-match between packet bytes and sent bytes: Sent: %d, Packet: %d \n",n,msg->N_bytes); + } + t_delta.tv_sec = t_now.tv_sec - m_t_last_dl.tv_sec; + t_delta.tv_usec = t_now.tv_sec - m_t_last_dl.tv_usec; + gettimeofday(&t_now, NULL); + if(t_delta.tv_sec>=5) + { + m_t_last_dl = t_now; + m_spgw_log->console("Sent %d bytes DL over the last %d.%d seconds. Bitrate = \n",msg->N_bytes, t_delta.tv_sec, t_delta.tv_usec/1000); + } return; } From a7b540c18e92e1b4ccf9c60fb923980cf57297b6 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 20 Feb 2018 18:55:13 +0000 Subject: [PATCH 112/342] Fixing bug in S1 Setup response. --- srsepc/src/main.cc | 1 + srsepc/src/mme/s1ap_mngmt_proc.cc | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index 89ae4c83e..3a931ddd2 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -204,6 +204,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { } args->mme_args.s1ap_args.mme_bind_addr = mme_bind_addr; + args->mme_args.s1ap_args.mme_name = mme_name; args->spgw_args.gtpu_bind_addr = spgw_bind_addr; args->spgw_args.sgi_if_addr = sgi_if_addr; args->hss_args.db_file = hss_db_file; diff --git a/srsepc/src/mme/s1ap_mngmt_proc.cc b/srsepc/src/mme/s1ap_mngmt_proc.cc index 43fa5d860..a4117d893 100644 --- a/srsepc/src/mme/s1ap_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_mngmt_proc.cc @@ -102,6 +102,7 @@ s1ap_mngmt_proc::handle_s1_setup_request(LIBLTE_S1AP_MESSAGE_S1SETUPREQUEST_STRU { //eNB already registered //TODO replace enb_ctx + m_s1ap_log->warning("eNB Already registered\n"); } else { @@ -218,11 +219,11 @@ s1ap_mngmt_proc::pack_s1_setup_response(s1ap_args_t s1ap_args, srslte::byte_buff succ->procedureCode = LIBLTE_S1AP_PROC_ID_S1SETUP; succ->criticality = LIBLTE_S1AP_CRITICALITY_IGNORE; succ->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_S1SETUPRESPONSE; - + LIBLTE_S1AP_MESSAGE_S1SETUPRESPONSE_STRUCT* s1_resp=(LIBLTE_S1AP_MESSAGE_S1SETUPRESPONSE_STRUCT*)&succ->choice; s1_resp->ext=false; - + //MME Name s1_resp->MMEname_present=true; s1_resp->MMEname.ext=false; From f6a17d118265f0ce3e40a390e521d6207a76dfe3 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 16 Feb 2018 12:05:45 +0100 Subject: [PATCH 113/342] Logs to test snr drop issue --- srsue/hdr/phy/phch_worker.h | 3 +++ srsue/src/phy/phch_recv.cc | 5 +++-- srsue/src/phy/phch_worker.cc | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index c154ff514..78389ccf7 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -70,6 +70,9 @@ public: void start_plot(); float get_ref_cfo(); + float get_snr(); + float get_rsrp(); + float get_noise(); float get_cfo(); float get_ul_cfo(); diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index bf09f5f34..80c972266 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -675,10 +675,11 @@ void phch_recv::run_thread() case 1: if (last_worker) { - Debug("SF: cfo_tot=%7.1f Hz, ref=%f Hz, pss=%f Hz\n", + Info("SF: cfo_tot=%7.1f Hz, ref=%f Hz, pss=%f Hz, snr_sf=%.2f dB, rsrp=%.2f dB, noise=%.2f dB\n", srslte_ue_sync_get_cfo(&ue_sync), 15000*last_worker->get_ref_cfo(), - 15000*ue_sync.strack.cfo_pss_mean); + 15000*ue_sync.strack.cfo_pss_mean, + last_worker->get_snr(), last_worker->get_rsrp(), last_worker->get_noise()); } last_worker = worker; diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index f7e1381f8..e6fb7f35a 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -203,6 +203,22 @@ float phch_worker::get_ref_cfo() return srslte_chest_dl_get_cfo(&ue_dl.chest); } +float phch_worker::get_snr() +{ + return 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)); +} + +float phch_worker::get_rsrp() +{ + return 10*log10(srslte_chest_dl_get_rsrp(&ue_dl.chest)); +} + +float phch_worker::get_noise() +{ + return 10*log10(srslte_chest_dl_get_noise_estimate(&ue_dl.chest)); +} + + float phch_worker::get_cfo() { return cfo; From d250dd51ad88f3e026c8e1d661841c869f229236 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 21 Feb 2018 11:51:08 +0100 Subject: [PATCH 114/342] Reduce LO leakage by not transmit signal on idle --- srsue/src/phy/phch_common.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_common.cc b/srsue/src/phy/phch_common.cc index b76b0d9ce..24c190361 100644 --- a/srsue/src/phy/phch_common.cc +++ b/srsue/src/phy/phch_common.cc @@ -62,9 +62,10 @@ phch_common::phch_common(uint32_t max_mutex_) : tx_mutex(max_mutex_) bzero(zeros, 50000*sizeof(cf_t)); // FIXME: This is an ugly fix to avoid the TX filters to empty + /* for (int i=0;i<50000;i++) { zeros[i] = 0.01*cexpf(((float) i/50000)*0.1*_Complex_I); - } + }*/ reset(); From 3a005af9f5356ada066a2f6c9dc4863afda6199e Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 21 Feb 2018 11:51:26 +0100 Subject: [PATCH 115/342] Normalize PUCCH power --- lib/src/phy/ue/ue_ul.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/ue/ue_ul.c b/lib/src/phy/ue/ue_ul.c index 5cf913bfa..b3842d0b7 100644 --- a/lib/src/phy/ue/ue_ul.c +++ b/lib/src/phy/ue/ue_ul.c @@ -355,7 +355,7 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data, } if (q->normalize_en) { - float norm_factor = (float) 0.8*q->cell.nof_prb/5; + float norm_factor = (float) q->cell.nof_prb/15/10; srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); } ret = SRSLTE_SUCCESS; From 56df710d1f3b9d84d18252cd169f0af98cd5398a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 21 Feb 2018 11:51:55 +0100 Subject: [PATCH 116/342] Add rx_gain_offset interface for RSRP calibration --- lib/include/srslte/interfaces/ue_interfaces.h | 1 + srsue/src/main.cc | 6 +++++- srsue/src/phy/phch_recv.cc | 2 +- srsue/src/phy/phch_worker.cc | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 454a18039..00b61fa1c 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -492,6 +492,7 @@ typedef struct { float estimator_fil_w; bool rssi_sensor_enabled; bool sic_pss_enabled; + float rx_gain_offset; } phy_args_t; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 4119b9f78..e76891796 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -162,7 +162,11 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { bpo::value(&args->expert.phy.rssi_sensor_enabled)->default_value(true), "Enable or disable RF frontend RSSI sensor. In some USRP devices can cause segmentation fault") - ("expert.prach_gain", + ("expert.rx_gain_offset", + bpo::value(&args->expert.phy.rx_gain_offset)->default_value(10), + "RX Gain offset to add to rx_gain to correct RSRP value") + + ("expert.prach_gain", bpo::value(&args->expert.phy.prach_gain)->default_value(-1.0), "Disable PRACH power control") diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 80c972266..7e6498157 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -675,7 +675,7 @@ void phch_recv::run_thread() case 1: if (last_worker) { - Info("SF: cfo_tot=%7.1f Hz, ref=%f Hz, pss=%f Hz, snr_sf=%.2f dB, rsrp=%.2f dB, noise=%.2f dB\n", + Debug("SF: cfo_tot=%7.1f Hz, ref=%f Hz, pss=%f Hz, snr_sf=%.2f dB, rsrp=%.2f dB, noise=%.2f dB\n", srslte_ue_sync_get_cfo(&ue_sync), 15000*last_worker->get_ref_cfo(), 15000*ue_sync.strack.cfo_pss_mean, diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index e6fb7f35a..b6878e6d8 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -1386,7 +1386,7 @@ void phch_worker::update_measurements() phy->last_radio_rssi = phy->get_radio()->get_rssi(); phy->rx_gain_offset = phy->avg_rssi_dbm - phy->last_radio_rssi + 30; } else { - phy->rx_gain_offset = phy->get_radio()->get_rx_gain(); + phy->rx_gain_offset = phy->get_radio()->get_rx_gain() + phy->args->rx_gain_offset; } } rssi_read_cnt++; From ff5ac85c7d09d0050fd61c4e0a41bca8a68a2e25 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 21 Feb 2018 14:50:41 +0100 Subject: [PATCH 117/342] Added int16 to float SIMD vector function --- lib/include/srslte/phy/utils/vector_simd.h | 2 ++ lib/src/phy/utils/test/vector_test.c | 25 +++++++++++++++++ lib/src/phy/utils/vector.c | 5 +--- lib/src/phy/utils/vector_simd.c | 32 +++++++++++++++++++++- 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/lib/include/srslte/phy/utils/vector_simd.h b/lib/include/srslte/phy/utils/vector_simd.h index 49268ca43..8139d0e78 100644 --- a/lib/include/srslte/phy/utils/vector_simd.h +++ b/lib/include/srslte/phy/utils/vector_simd.h @@ -120,6 +120,8 @@ SRSLTE_API void srslte_vec_abs_square_cf_simd(const cf_t *x, float *z, const int /* Other Functions */ SRSLTE_API void srslte_vec_lut_sss_simd(const short *x, const unsigned short *lut, short *y, const int len); +SRSLTE_API void srslte_vec_convert_if_simd(const int16_t *x, float *z, const float scale, const int len); + SRSLTE_API void srslte_vec_convert_fi_simd(const float *x, int16_t *z, const float scale, const int len); SRSLTE_API void srslte_vec_cp_simd(const cf_t *src, cf_t *dst, int len); diff --git a/lib/src/phy/utils/test/vector_test.c b/lib/src/phy/utils/test/vector_test.c index ebda516ea..f0b954bad 100644 --- a/lib/src/phy/utils/test/vector_test.c +++ b/lib/src/phy/utils/test/vector_test.c @@ -452,6 +452,28 @@ TEST(srslte_vec_convert_fi, free(z); ) +TEST(srslte_vec_convert_if, + MALLOC(int16_t, x); + MALLOC(float, z); + float scale = 1000.0f; + + float gold; + float k = 1.0f/scale; + for (int i = 0; i < block_size; i++) { + x[i] = (int16_t) RANDOM_S(); + } + + TEST_CALL(srslte_vec_convert_if(x, scale, z, block_size)) + + for (int i = 0; i < block_size; i++) { + gold = ((float)x[i]) * k; + mse += fabsf(gold - z[i]); + } + + free(x); + free(z); +) + TEST(srslte_vec_prod_fff, MALLOC(float, x); MALLOC(float, y); @@ -753,6 +775,9 @@ int main(int argc, char **argv) { passed[func_count][size_count] = test_srslte_vec_convert_fi(func_names[func_count], &timmings[func_count][size_count], block_size); func_count++; + passed[func_count][size_count] = test_srslte_vec_convert_if(func_names[func_count], &timmings[func_count][size_count], block_size); + func_count++; + passed[func_count][size_count] = test_srslte_vec_prod_fff(func_names[func_count], &timmings[func_count][size_count], block_size); func_count++; diff --git a/lib/src/phy/utils/vector.c b/lib/src/phy/utils/vector.c index 195ac98cb..b97583bb8 100644 --- a/lib/src/phy/utils/vector.c +++ b/lib/src/phy/utils/vector.c @@ -93,10 +93,7 @@ void srslte_vec_sc_prod_ccc(const cf_t *x, const cf_t h, cf_t *z, const uint32_t // Used in turbo decoder void srslte_vec_convert_if(const int16_t *x, const float scale, float *z, const uint32_t len) { - int i; - for (i=0;i Date: Mon, 19 Feb 2018 19:15:38 +0100 Subject: [PATCH 118/342] UE stores last PMI and last RI in common phy --- lib/src/phy/ue/ue_dl.c | 12 ++++++------ srsue/hdr/phy/phch_common.h | 3 +++ srsue/src/phy/phch_common.cc | 2 ++ srsue/src/phy/phch_worker.cc | 35 +++++++++++++++++------------------ 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/lib/src/phy/ue/ue_dl.c b/lib/src/phy/ue/ue_dl.c index 491e676bf..3815041a7 100644 --- a/lib/src/phy/ue/ue_dl.c +++ b/lib/src/phy/ue/ue_dl.c @@ -460,15 +460,15 @@ int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint3 pmi = grant->pinfo - 1; } else { ERROR("Not Implemented (nof_tb=%d, pinfo=%d)", nof_tb, grant->pinfo); - return SRSLTE_ERROR; + pmi = grant->pinfo % 4; } } else { - if (grant->pinfo < 2) { - pmi = grant->pinfo; - } else { - ERROR("Not Implemented (nof_tb=%d, pinfo=%d)", nof_tb, grant->pinfo); - return SRSLTE_ERROR; + if (grant->pinfo == 2) { + ERROR("Not implemented codebook index (nof_tb=%d, pinfo=%d)", nof_tb, grant->pinfo); + } else if (grant->pinfo > 2) { + ERROR("Reserved codebook index (nof_tb=%d, pinfo=%d)", nof_tb, grant->pinfo); } + pmi = grant->pinfo % 2; } } if(SRSLTE_SF_MBSFN == grant->sf_type) { diff --git a/srsue/hdr/phy/phch_common.h b/srsue/hdr/phy/phch_common.h index 31bf06122..f21738b6b 100644 --- a/srsue/hdr/phy/phch_common.h +++ b/srsue/hdr/phy/phch_common.h @@ -87,6 +87,9 @@ public: uint32_t last_ul_tti[2*HARQ_DELAY_MS]; srslte_mod_t last_ul_mod[2*HARQ_DELAY_MS]; + uint8_t last_ri; + uint8_t last_pmi; + phch_common(uint32_t max_mutex = 3); void init(phy_interface_rrc::phy_cfg_t *config, phy_args_t *args, diff --git a/srsue/src/phy/phch_common.cc b/srsue/src/phy/phch_common.cc index 24c190361..65681c8c6 100644 --- a/srsue/src/phy/phch_common.cc +++ b/srsue/src/phy/phch_common.cc @@ -48,6 +48,8 @@ phch_common::phch_common(uint32_t max_mutex_) : tx_mutex(max_mutex_) max_mutex = max_mutex_; nof_mutex = 0; rx_gain_offset = 0; + last_ri = 0; + last_pmi = 0; bzero(&dl_metrics, sizeof(dl_metrics_t)); dl_metrics_read = true; diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index b6878e6d8..6a533759b 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -890,19 +890,20 @@ void phch_worker::set_uci_periodic_cqi() int cqi_fixed = phy->args->cqi_fixed; int cqi_max = phy->args->cqi_max; - uint8_t ri = (uint8_t) ue_dl.ri; - uint8_t pmi = (uint8_t) ue_dl.pmi[ri]; - float sinr = ue_dl.sinr[ri][pmi]; + float sinr = ue_dl.sinr[phy->last_ri & SRSLTE_MAX_LAYERS][phy->last_pmi % SRSLTE_MAX_CODEBOOKS]; if (period_cqi.configured && rnti_is_set) { if (period_cqi.ri_idx_present && srslte_ri_send(period_cqi.pmi_idx, period_cqi.ri_idx, TTI_TX(tti))) { /* Compute RI, PMI and SINR */ - compute_ri(&ri, &pmi, &sinr); - uci_data.uci_ri = ri; + compute_ri(&phy->last_ri, &phy->last_pmi, &sinr); + uci_data.uci_ri = phy->last_ri; uci_data.uci_ri_len = 1; uci_data.ri_periodic_report = true; - Debug("PUCCH: Periodic ri=%d\n", ri); + Debug("PUCCH: Periodic ri=%d, SINR=%.1f\n", phy->last_ri, sinr); } else if (srslte_cqi_send(period_cqi.pmi_idx, TTI_TX(tti))) { + compute_ri(NULL, NULL, NULL); + phy->last_pmi = (uint8_t) ue_dl.pmi[phy->last_ri % SRSLTE_MAX_LAYERS]; + srslte_cqi_value_t cqi_report = {0}; if (period_cqi.format_is_subband) { // TODO: Implement subband periodic reports @@ -923,8 +924,8 @@ void phch_worker::set_uci_periodic_cqi() } if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4) { cqi_report.wideband.pmi_present = true; - cqi_report.wideband.pmi = pmi; - cqi_report.wideband.rank_is_not_one = (ri != 0); + cqi_report.wideband.pmi = phy->last_pmi; + cqi_report.wideband.rank_is_not_one = (phy->last_ri != 0); } Debug("PUCCH: Periodic CQI=%d, SNR=%.1f dB\n", cqi_report.wideband.wideband_cqi, phy->avg_snr_db); } @@ -936,13 +937,11 @@ void phch_worker::set_uci_periodic_cqi() void phch_worker::set_uci_aperiodic_cqi() { - uint8_t ri = (uint8_t) ue_dl.ri; - uint8_t pmi = (uint8_t) ue_dl.pmi[ri]; - float sinr_db = ue_dl.sinr[ri][pmi]; + float sinr_db = ue_dl.sinr[phy->last_ri % SRSLTE_MAX_LAYERS][phy->last_pmi%SRSLTE_MAX_CODEBOOKS]; if (phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic_present) { /* Compute RI, PMI and SINR */ - compute_ri(&ri, &pmi, &sinr_db); + compute_ri(&phy->last_ri, &phy->last_pmi, &sinr_db); switch(phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic) { case LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM30: @@ -977,7 +976,7 @@ void phch_worker::set_uci_aperiodic_cqi() /* Set RI = 1 */ if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_3 || phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4) { - uci_data.uci_ri = ri; + uci_data.uci_ri = phy->last_ri; uci_data.uci_ri_len = 1; } else { uci_data.uci_ri_len = 0; @@ -1007,13 +1006,13 @@ void phch_worker::set_uci_aperiodic_cqi() cqi_report.subband_hl.wideband_cqi_cw0 = srslte_cqi_from_snr(sinr_db); cqi_report.subband_hl.subband_diff_cqi_cw0 = 0; // Always report zero offset on all subbands - if (ri > 0) { + if (phy->last_ri > 0) { cqi_report.subband_hl.rank_is_not_one = true; cqi_report.subband_hl.wideband_cqi_cw1 = srslte_cqi_from_snr(sinr_db); cqi_report.subband_hl.subband_diff_cqi_cw1 = 0; // Always report zero offset on all subbands } - cqi_report.subband_hl.pmi = pmi; + cqi_report.subband_hl.pmi = phy->last_pmi; cqi_report.subband_hl.pmi_present = true; cqi_report.subband_hl.four_antenna_ports = (cell.nof_ports == 4); @@ -1027,7 +1026,7 @@ void phch_worker::set_uci_aperiodic_cqi() } uci_data.uci_cqi_len = (uint32_t) cqi_len; uci_data.uci_ri_len = 1; - uci_data.uci_ri = ri; + uci_data.uci_ri = phy->last_ri; char cqi_str[SRSLTE_CQI_STR_MAX_CHAR] = {0}; srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, SRSLTE_CQI_STR_MAX_CHAR); @@ -1035,11 +1034,11 @@ void phch_worker::set_uci_aperiodic_cqi() if (cqi_report.subband_hl.rank_is_not_one) { Info("PUSCH: Aperiodic RM31 ri~1, CQI=%02d/%02d, SINR=%2.1f/%2.1fdB, pmi=%d for %d subbands\n", cqi_report.subband_hl.wideband_cqi_cw0, cqi_report.subband_hl.wideband_cqi_cw1, - sinr_db, sinr_db, pmi, cqi_report.subband_hl.N); + sinr_db, sinr_db, phy->last_pmi, cqi_report.subband_hl.N); } else { Info("PUSCH: Aperiodic RM31 ri=1, CQI=%02d, SINR=%2.1f, pmi=%d for %d subbands\n", cqi_report.subband_hl.wideband_cqi_cw0, - sinr_db, pmi, cqi_report.subband_hl.N); + sinr_db, phy->last_pmi, cqi_report.subband_hl.N); } } break; From 2c8467780dbf447e0139655db63e8a409fd07898 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 21 Feb 2018 16:15:51 +0100 Subject: [PATCH 119/342] UE stores last PMI and last RI in common phy --- lib/include/srslte/phy/utils/vector_simd.h | 2 ++ lib/src/phy/utils/test/vector_test.c | 37 ++++++++++++++++++---- lib/src/phy/utils/vector.c | 5 +-- lib/src/phy/utils/vector_simd.c | 32 ++++++++++++++++++- 4 files changed, 65 insertions(+), 11 deletions(-) diff --git a/lib/include/srslte/phy/utils/vector_simd.h b/lib/include/srslte/phy/utils/vector_simd.h index 49268ca43..8139d0e78 100644 --- a/lib/include/srslte/phy/utils/vector_simd.h +++ b/lib/include/srslte/phy/utils/vector_simd.h @@ -120,6 +120,8 @@ SRSLTE_API void srslte_vec_abs_square_cf_simd(const cf_t *x, float *z, const int /* Other Functions */ SRSLTE_API void srslte_vec_lut_sss_simd(const short *x, const unsigned short *lut, short *y, const int len); +SRSLTE_API void srslte_vec_convert_if_simd(const int16_t *x, float *z, const float scale, const int len); + SRSLTE_API void srslte_vec_convert_fi_simd(const float *x, int16_t *z, const float scale, const int len); SRSLTE_API void srslte_vec_cp_simd(const cf_t *src, cf_t *dst, int len); diff --git a/lib/src/phy/utils/test/vector_test.c b/lib/src/phy/utils/test/vector_test.c index ebda516ea..55ff2944e 100644 --- a/lib/src/phy/utils/test/vector_test.c +++ b/lib/src/phy/utils/test/vector_test.c @@ -452,6 +452,28 @@ TEST(srslte_vec_convert_fi, free(z); ) +TEST(srslte_vec_convert_if, + MALLOC(int16_t, x); + MALLOC(float, z); + float scale = 1000.0f; + + float gold; + float k = 1.0f/scale; + for (int i = 0; i < block_size; i++) { + x[i] = (int16_t) RANDOM_S(); + } + + TEST_CALL(srslte_vec_convert_if(x, scale, z, block_size)) + + for (int i = 0; i < block_size; i++) { + gold = ((float)x[i]) * k; + mse += fabsf(gold - z[i]); + } + + free(x); + free(z); +) + TEST(srslte_vec_prod_fff, MALLOC(float, x); MALLOC(float, y); @@ -596,7 +618,7 @@ TEST(srslte_vec_div_ccc, for (int i = 0; i < block_size; i++) { gold = x[i] / y[i]; - mse += cabsf(gold - z[i]); + mse += cabsf(gold - z[i]) / cabsf(gold); } mse /= block_size; @@ -614,14 +636,14 @@ TEST(srslte_vec_div_cfc, cf_t gold; for (int i = 0; i < block_size; i++) { x[i] = RANDOM_CF(); - y[i] = RANDOM_F(); + y[i] = RANDOM_F() + 0.0001f; } TEST_CALL(srslte_vec_div_cfc(x, y, z, block_size)) for (int i = 0; i < block_size; i++) { gold = x[i] / y[i]; - mse += cabsf(gold - z[i])/cabsf(gold); + mse += cabsf(gold - z[i]) / cabsf(gold); } mse /= block_size; @@ -638,15 +660,15 @@ TEST(srslte_vec_div_fff, cf_t gold; for (int i = 0; i < block_size; i++) { - x[i] = RANDOM_F() + 0.0001; - y[i] = RANDOM_F()+ 0.0001; + x[i] = RANDOM_F(); + y[i] = RANDOM_F() + 0.0001f; } TEST_CALL(srslte_vec_div_fff(x, y, z, block_size)) for (int i = 0; i < block_size; i++) { gold = x[i] / y[i]; - mse += cabsf(gold - z[i]); + mse += cabsf(gold - z[i]) / cabsf(gold); } mse /= block_size; @@ -753,6 +775,9 @@ int main(int argc, char **argv) { passed[func_count][size_count] = test_srslte_vec_convert_fi(func_names[func_count], &timmings[func_count][size_count], block_size); func_count++; + passed[func_count][size_count] = test_srslte_vec_convert_if(func_names[func_count], &timmings[func_count][size_count], block_size); + func_count++; + passed[func_count][size_count] = test_srslte_vec_prod_fff(func_names[func_count], &timmings[func_count][size_count], block_size); func_count++; diff --git a/lib/src/phy/utils/vector.c b/lib/src/phy/utils/vector.c index 195ac98cb..b97583bb8 100644 --- a/lib/src/phy/utils/vector.c +++ b/lib/src/phy/utils/vector.c @@ -93,10 +93,7 @@ void srslte_vec_sc_prod_ccc(const cf_t *x, const cf_t h, cf_t *z, const uint32_t // Used in turbo decoder void srslte_vec_convert_if(const int16_t *x, const float scale, float *z, const uint32_t len) { - int i; - for (i=0;i Date: Thu, 22 Feb 2018 12:13:53 +0100 Subject: [PATCH 120/342] Stop RX stream when cell not found during initial cell search --- lib/src/phy/rf/rf_utils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/phy/rf/rf_utils.c b/lib/src/phy/rf/rf_utils.c index 4587ebdcb..f12054e9d 100644 --- a/lib/src/phy/rf/rf_utils.c +++ b/lib/src/phy/rf/rf_utils.c @@ -186,9 +186,11 @@ int rf_cell_search(srslte_rf_t *rf, uint32_t nof_rx_antennas, ret = srslte_ue_cellsearch_scan(&cs, found_cells, &max_peak_cell); } if (ret < 0) { + srslte_rf_stop_rx_stream(rf); fprintf(stderr, "Error searching cell\n"); return SRSLTE_ERROR; } else if (ret == 0) { + srslte_rf_stop_rx_stream(rf); fprintf(stderr, "Could not find any cell in this frequency\n"); return SRSLTE_SUCCESS; } From 543cdf8566527a4b590dd11109a57ebe5fcf5897 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 22 Feb 2018 11:51:57 +0000 Subject: [PATCH 121/342] Adding handling of service request when no ECM context is present. --- srsepc/src/mme/s1ap_nas_transport.cc | 21 +++++++++++++++++++++ srsepc/src/spgw/spgw.cc | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 96834c3ba..2fa520c2f 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -651,9 +651,30 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, } else { + ue_ecm_ctx_t ue_ecm_ctx; //UE not connect. Connect normally. m_s1ap_log->console("Service Request -- User without ECM context\n"); m_s1ap_log->info("Service Request -- User without ECM context\n"); + //Create ECM context + ue_ecm_ctx.imsi = ue_emm_ctx->imsi; + ue_ecm_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + ue_emm_ctx->mme_ue_s1ap_id = ue_ecm_ctx.mme_ue_s1ap_id; + //Set eNB information + ue_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; + memcpy(&ue_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + + //Save whether secure ESM information transfer is necessary + ue_ecm_ctx.eit = false; + + //Initialize E-RABs + for(uint i = 0 ; i< MAX_ERABS_PER_UE; i++) + { + ue_ecm_ctx.erabs_ctx[i].state = ERAB_DEACTIVATED; + ue_ecm_ctx.erabs_ctx[i].erab_id = i; + } + memcpy(&ue_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); + m_mme_gtpc->send_create_session_request(ue_ecm_ctx.imsi, ue_ecm_ctx.mme_ue_s1ap_id); } } else diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index 55f19818d..7bc47f496 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -385,9 +385,10 @@ spgw::handle_sgi_pdu(srslte::byte_buffer_t *msg) { m_spgw_log->error("Mis-match between packet bytes and sent bytes: Sent: %d, Packet: %d \n",n,msg->N_bytes); } + + gettimeofday(&t_now, NULL); t_delta.tv_sec = t_now.tv_sec - m_t_last_dl.tv_sec; t_delta.tv_usec = t_now.tv_sec - m_t_last_dl.tv_usec; - gettimeofday(&t_now, NULL); if(t_delta.tv_sec>=5) { m_t_last_dl = t_now; From b233e9e1aeea153d5ada13700592bcbfdb3a1ed1 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 22 Feb 2018 15:50:05 +0000 Subject: [PATCH 122/342] Fixing bug with k_enb generation. Fixing issue with enb_ue_s1ap_id for service requests without ECM context. --- srsepc/src/mme/s1ap_nas_transport.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index e8c7f1815..627851d59 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -472,6 +472,10 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, std::map::iterator it = m_s1ap->m_tmsi_to_imsi.find(m_tmsi); if(it == m_s1ap->m_tmsi_to_imsi.end()) { + + m_s1ap_log->console("Attach Request -- Could not find M-TMSI 0x%x", m_tmsi); + m_s1ap_log->info("Attach Request -- Could not find M-TMSI 0x%x", m_tmsi); + //Could not find IMSI from M-TMSI, send Id request ue_emm_ctx_t tmp_ue_emm_ctx; ue_ecm_ctx_t ue_ecm_ctx; @@ -653,6 +657,8 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, else { ue_ecm_ctx_t ue_ecm_ctx; + ue_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; + //UE not connect. Connect normally. m_s1ap_log->console("Service Request -- User without ECM context\n"); m_s1ap_log->info("Service Request -- User without ECM context\n"); @@ -675,6 +681,10 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, } memcpy(&ue_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); + + //Re-generate K_eNB + liblte_security_generate_k_enb(ue_emm_ctx->security_ctxt.k_asme, ue_emm_ctx->security_ctxt.ul_nas_count, ue_emm_ctx->security_ctxt.k_enb); + m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",ue_emm_ctx->security_ctxt.ul_nas_count); m_mme_gtpc->send_create_session_request(ue_ecm_ctx.imsi, ue_ecm_ctx.mme_ue_s1ap_id); } } From 7dd734510bafdd11014bd690d9a55950dd541015 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 22 Feb 2018 18:38:25 +0000 Subject: [PATCH 123/342] added EMM cause 'CS not avilable' and ESM cause 'PDN type only IPv4 allowed.' --- srsepc/src/mme/s1ap_nas_transport.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 627851d59..58872b194 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -1561,10 +1561,13 @@ s1ap_nas_transport::pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *u attach_accept.guti.guti.mme_code, attach_accept.guti.guti.m_tmsi); + //Set EMM cause to no CS available + attach_accept.emm_cause_present=true; + attach_accept.emm_cause=18; + //Make sure all unused options are set to false attach_accept.lai_present=false; attach_accept.ms_id_present=false; - attach_accept.emm_cause_present=false; attach_accept.t3402_present=false; attach_accept.t3423_present=false; attach_accept.equivalent_plmns_present=false; @@ -1608,7 +1611,8 @@ s1ap_nas_transport::pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *u act_def_eps_bearer_context_req.radio_prio_present = false; act_def_eps_bearer_context_req.packet_flow_id_present = false; act_def_eps_bearer_context_req.apn_ambr_present = false; - act_def_eps_bearer_context_req.esm_cause_present = false; + act_def_eps_bearer_context_req.esm_cause_present = true; + act_def_eps_bearer_context_req.esm_cause = 50; uint8_t sec_hdr_type =2; ue_emm_ctx->security_ctxt.dl_nas_count++; From 7e091b8e6057f583ef6337777b1fbdc90d9325db Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 23 Feb 2018 10:12:44 +0100 Subject: [PATCH 124/342] Fix Underflow when PHY Reset --- srsue/src/phy/phy.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 4417beb86..cf8ae33f8 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -366,7 +366,6 @@ void phy::reset() workers[i].reset(); } workers_common.reset(); - usleep(4000); workers_common.reset_ul(); } From d913fdd499cee9760dccbbc4fe134b5aa5c23166 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 23 Feb 2018 10:18:13 +0000 Subject: [PATCH 125/342] Adding EMM information message. --- srsepc/hdr/mme/s1ap_nas_transport.h | 2 +- srsepc/src/mme/s1ap_nas_transport.cc | 46 ++++++++++++++++++---------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index b8eb98805..63253dcb0 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -94,7 +94,7 @@ public: bool pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *ue_ecm_ctx, LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *erab_ctxt, struct srslte::gtpc_pdn_address_allocation_ie *paa, srslte::byte_buffer_t *nas_buffer); bool pack_identity_request(srslte::byte_buffer_t *reply_msg, uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id); - bool pack_emm_information(srslte::byte_buffer_t *reply_msg, uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id); + bool pack_emm_information(ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg); void log_unhandled_attach_request_ies(const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT *attach_req); void log_unhandled_pdn_con_request_ies(const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT *pdn_con_req); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 58872b194..b5c2b8531 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -837,6 +837,13 @@ s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, u return false; } m_mme_gtpc->send_modify_bearer_request(&ue_ecm_ctx->erabs_ctx[act_bearer.eps_bearer_id]); + + //Send reply to eNB + m_s1ap_log->console("Packing EMM infromationi\n"); + *reply_flag = pack_emm_information(ue_ecm_ctx, reply_msg); + m_s1ap_log->console("Sending EMM infromation, bytes %d\n",reply_msg->N_bytes); + m_s1ap_log->info("Sending EMM infromation\n"); + return true; } @@ -1536,6 +1543,7 @@ s1ap_nas_transport::pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *u //Attach accept attach_accept.eps_attach_result = LIBLTE_MME_EPS_ATTACH_RESULT_EPS_ONLY; + //attach_accept.eps_attach_result = LIBLTE_MME_EPS_ATTACH_RESULT_COMBINED_EPS_IMSI_ATTACH; //Mandatory //FIXME: Set t3412 from config attach_accept.t3412.unit = LIBLTE_MME_GPRS_TIMER_UNIT_1_MINUTE; // GPRS 1 minute unit @@ -1562,6 +1570,7 @@ s1ap_nas_transport::pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *u attach_accept.guti.guti.m_tmsi); //Set EMM cause to no CS available + //attach_accept.emm_cause_present=false; attach_accept.emm_cause_present=true; attach_accept.emm_cause=18; @@ -1611,8 +1620,8 @@ s1ap_nas_transport::pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *u act_def_eps_bearer_context_req.radio_prio_present = false; act_def_eps_bearer_context_req.packet_flow_id_present = false; act_def_eps_bearer_context_req.apn_ambr_present = false; - act_def_eps_bearer_context_req.esm_cause_present = true; - act_def_eps_bearer_context_req.esm_cause = 50; + act_def_eps_bearer_context_req.esm_cause_present = false; + //act_def_eps_bearer_context_req.esm_cause = 50; uint8_t sec_hdr_type =2; ue_emm_ctx->security_ctxt.dl_nas_count++; @@ -1692,7 +1701,7 @@ s1ap_nas_transport::pack_identity_request(srslte::byte_buffer_t *reply_msg, uint } bool -s1ap_nas_transport::pack_emm_information(srslte::byte_buffer_t *reply_msg, uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id) +s1ap_nas_transport::pack_emm_information( ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_msg) { srslte::byte_buffer_t *nas_buffer = m_pool->allocate(); @@ -1710,8 +1719,8 @@ s1ap_nas_transport::pack_emm_information(srslte::byte_buffer_t *reply_msg, uint3 //Setup Dw NAS structure LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT *dw_nas = &init->choice.DownlinkNASTransport; dw_nas->ext=false; - dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = mme_ue_s1ap_id;//FIXME Change name - dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = enb_ue_s1ap_id; + dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ecm_ctx->mme_ue_s1ap_id;//FIXME Change name + dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ecm_ctx->enb_ue_s1ap_id; dw_nas->HandoverRestrictionList_present=false; dw_nas->SubscriberProfileIDforRFP_present=false; @@ -1727,20 +1736,12 @@ s1ap_nas_transport::pack_emm_information(srslte::byte_buffer_t *reply_msg, uint3 emm_info.utc_and_local_time_zone_present = false; emm_info.net_dst_present = false; - //Integrity check - ue_ecm_ctx_t * ue_ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); - if(ue_ecm_ctx == NULL) - { - return false; - } - ue_emm_ctx_t * ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); - if(ue_emm_ctx == NULL) - { + ue_emm_ctx_t *ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); + if(ue_emm_ctx ==NULL) return false; - } uint8_t sec_hdr_type =2; - ue_emm_ctx->security_ctxt.dl_nas_count++; + //ue_emm_ctx->security_ctxt.dl_nas_count++; LIBLTE_ERROR_ENUM err = liblte_mme_pack_emm_information_msg(&emm_info, sec_hdr_type, ue_emm_ctx->security_ctxt.dl_nas_count, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); if(err != LIBLTE_SUCCESS) { @@ -1760,9 +1761,20 @@ s1ap_nas_transport::pack_emm_information(srslte::byte_buffer_t *reply_msg, uint3 ); memcpy(&nas_buffer->msg[1],mac,4); + //Copy NAS PDU to Downlink NAS Trasport message buffer + memcpy(dw_nas->NAS_PDU.buffer, nas_buffer->msg, nas_buffer->N_bytes); + dw_nas->NAS_PDU.n_octets = nas_buffer->N_bytes; + //Pack Downlink NAS Transport Message + err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_msg); + if(err != LIBLTE_SUCCESS) + { + m_s1ap_log->error("Error packing Dw NAS Transport: EMM Info\n"); + m_s1ap_log->console("Error packing Downlink NAS Transport: EMM Info\n"); + return false; + } - m_s1ap_log->info("Packed \n"); + m_s1ap_log->info("Packed UE EMM information\n"); return true; } From 8474c6e3aac854bd7320158741fd9110b192d0ec Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 23 Feb 2018 13:05:02 +0100 Subject: [PATCH 126/342] Fixed HO to unkown cell issue --- srsue/hdr/upper/rrc.h | 112 +++++++++++++++++- srsue/src/upper/rrc.cc | 259 ++++++++++++++++++++++++----------------- 2 files changed, 258 insertions(+), 113 deletions(-) diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 1aaf6f29b..5f269ec86 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -65,12 +65,14 @@ class cell_t return earfcn == this->earfcn && pci == phy_cell.id; } bool greater(cell_t *x) { - return x->rsrp > rsrp; + return rsrp > x->rsrp; } bool plmn_equals(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { - for (uint32_t i = 0; i < sib1.N_plmn_ids; i++) { - if (plmn_id.mcc == sib1.plmn_id[i].id.mcc && plmn_id.mnc == sib1.plmn_id[i].id.mnc) { - return true; + if (has_valid_sib1) { + for (uint32_t i = 0; i < sib1.N_plmn_ids; i++) { + if (plmn_id.mcc == sib1.plmn_id[i].id.mcc && plmn_id.mnc == sib1.plmn_id[i].id.mnc) { + return true; + } } } return false; @@ -80,6 +82,7 @@ class cell_t cell_t(tmp, 0, 0); } cell_t(srslte_cell_t phy_cell, uint32_t earfcn, float rsrp) { + gettimeofday(&last_update, NULL); this->has_valid_sib1 = false; this->has_valid_sib2 = false; this->has_valid_sib3 = false; @@ -94,14 +97,106 @@ class cell_t bzero(&sib13, sizeof(sib13)); } - uint32_t earfcn; + uint32_t get_earfcn() { + return earfcn; + } + + uint32_t get_pci() { + return phy_cell.id; + } + + void set_rsrp(float rsrp) { + this->rsrp = rsrp; + in_sync = true; + gettimeofday(&last_update, NULL); + } + + float get_rsrp() { + return rsrp; + } + + void set_sib1(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT *sib1) { + memcpy(&this->sib1, sib1, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT)); + has_valid_sib1 = true; + } + void set_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2) { + memcpy(&this->sib2, sib2, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT)); + has_valid_sib2 = true; + } + void set_sib3(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3_STRUCT *sib3) { + memcpy(&this->sib3, sib3, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3_STRUCT)); + has_valid_sib3 = true; + } + void set_sib13(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13_STRUCT *sib13) { + memcpy(&this->sib13, sib13, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13_STRUCT)); + has_valid_sib13 = true; + } + + uint32_t timeout_secs(struct timeval now) { + struct timeval t[3]; + memcpy(&t[2], &now, sizeof(struct timeval)); + memcpy(&t[1], &last_update, sizeof(struct timeval)); + get_time_interval(t); + return t[0].tv_sec; + } + + LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT *sib1ptr() { + return &sib1; + } + LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2ptr() { + return &sib2; + } + LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3_STRUCT *sib3ptr() { + return &sib3; + } + + uint32_t get_cell_id() { + return sib1.cell_id; + } + + bool has_sib1() { + return has_valid_sib1; + } + bool has_sib2() { + return has_valid_sib2; + } + bool has_sib3() { + return has_valid_sib3; + } + bool has_sib13() { + return has_valid_sib13; + } + + uint16_t get_mcc() { + if (has_valid_sib1) { + if (sib1.N_plmn_ids > 0) { + return sib1.plmn_id[0].id.mcc; + } + } + return 0; + } + + uint16_t get_mnc() { + if (has_valid_sib1) { + if (sib1.N_plmn_ids > 0) { + return sib1.plmn_id[0].id.mnc; + } + } + return 0; + } + srslte_cell_t phy_cell; + bool in_sync; + + private: float rsrp; + uint32_t earfcn; + struct timeval last_update; + bool has_valid_sib1; bool has_valid_sib2; bool has_valid_sib3; bool has_valid_sib13; - bool in_sync; LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT sib1; LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT sib2; LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3_STRUCT sib3; @@ -274,6 +369,7 @@ private: } // List of strongest neighbour cell + const static int NEIGHBOUR_TIMEOUT = 5; const static int NOF_NEIGHBOUR_CELLS = 8; std::vector neighbour_cells; cell_t *serving_cell; @@ -285,6 +381,9 @@ private: bool add_neighbour_cell(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp); bool add_neighbour_cell(cell_t *cell); void sort_neighbour_cells(); + void clean_neighbours(); + std::vector::iterator delete_neighbour(std::vector::iterator it); + void delete_neighbour(uint32_t cell_idx); typedef enum { SI_ACQUIRE_IDLE = 0, @@ -315,6 +414,7 @@ private: void run_tti(uint32_t tti); bool timer_expired(uint32_t timer_id); void ho_finish(); + void delete_report(uint32_t earfcn, uint32_t pci); private: const static int NOF_MEASUREMENTS = 3; diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 4d93c9452..9e26436ae 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -54,6 +54,7 @@ rrc::rrc() n310_cnt = 0; n311_cnt = 0; serving_cell = new cell_t(); + neighbour_cells.reserve(NOF_NEIGHBOUR_CELLS); } rrc::~rrc() @@ -168,6 +169,7 @@ void rrc::set_args(rrc_args_t *args) { void rrc::run_thread() { uint32_t failure_test = 0; + uint32_t cell_clean_cnt = 0; while (thread_running) { @@ -217,13 +219,13 @@ void rrc::run_thread() { * Cell is selected when all SIBs downloaded or applied. */ if (phy->sync_status()) { - if (!serving_cell->has_valid_sib1) { + if (!serving_cell->has_sib1()) { si_acquire_state = SI_ACQUIRE_SIB1; sysinfo_index = 0; - } else if (!serving_cell->has_valid_sib2) { + } else if (!serving_cell->has_sib2()) { si_acquire_state = SI_ACQUIRE_SIB2; } else { - apply_sib2_configs(&serving_cell->sib2); + apply_sib2_configs(serving_cell->sib2ptr()); si_acquire_state = SI_ACQUIRE_IDLE; state = RRC_STATE_CELL_SELECTED; } @@ -302,6 +304,13 @@ void rrc::run_thread() { default: break; } + if (state == RRC_STATE_CONNECTED || RRC_STATE_IDLE) { + cell_clean_cnt++; + if (cell_clean_cnt==1000) { + clean_neighbours(); + cell_clean_cnt = 0; + } + } usleep(1000); } } @@ -363,16 +372,16 @@ void rrc::run_si_acquisition_procedure() break; case SI_ACQUIRE_SIB2: // Instruct MAC to look for next SIB - if(sysinfo_index < serving_cell->sib1.N_sched_info) { - si_win_len = liblte_rrc_si_window_length_num[serving_cell->sib1.si_window_length]; + if(sysinfo_index < serving_cell->sib1ptr()->N_sched_info) { + si_win_len = liblte_rrc_si_window_length_num[serving_cell->sib1ptr()->si_window_length]; x = sysinfo_index*si_win_len; sf = x%10; offset = x/10; tti = mac->get_current_tti(); - period = liblte_rrc_si_periodicity_num[serving_cell->sib1.sched_info[sysinfo_index].si_periodicity]; + period = liblte_rrc_si_periodicity_num[serving_cell->sib1ptr()->sched_info[sysinfo_index].si_periodicity]; si_win_start = sib_start_tti(tti, period, offset, sf); - si_win_len = liblte_rrc_si_window_length_num[serving_cell->sib1.si_window_length]; + si_win_len = liblte_rrc_si_window_length_num[serving_cell->sib1ptr()->si_window_length]; if (last_win_start == 0 || (srslte_tti_interval(last_win_start, tti) > period*10 && srslte_tti_interval(last_win_start, tti) < 1000)) @@ -416,17 +425,11 @@ void rrc::run_si_acquisition_procedure() *******************************************************************************/ uint16_t rrc::get_mcc() { - if (serving_cell->sib1.N_plmn_ids > 0) { - return serving_cell->sib1.plmn_id[0].id.mcc; - } - return 0; + return serving_cell->get_mcc(); } uint16_t rrc::get_mnc() { - if (serving_cell->sib1.N_plmn_ids > 0) { - return serving_cell->sib1.plmn_id[0].id.mnc; - } - return 0; + return serving_cell->get_mnc(); } void rrc::plmn_search() { @@ -491,7 +494,7 @@ void rrc::set_serving_cell(uint32_t cell_idx) { // Move serving cell to neighbours list if (serving_cell->is_valid()) { // Make sure it does not exist already - int serving_idx = find_neighbour_cell(serving_cell->earfcn, serving_cell->phy_cell.id); + int serving_idx = find_neighbour_cell(serving_cell->get_earfcn(), serving_cell->phy_cell.id); if (serving_idx >= 0 && (uint32_t) serving_idx < neighbour_cells.size()) { printf("Error serving cell is already in the neighbour list. Removing it\n"); neighbour_cells.erase(std::remove(neighbour_cells.begin(), neighbour_cells.end(), neighbour_cells[serving_idx]), neighbour_cells.end()); @@ -506,7 +509,7 @@ void rrc::set_serving_cell(uint32_t cell_idx) { serving_cell = new_serving_cell; rrc_log->info("Setting serving cell idx=%d, earfcn=%d, PCI=%d, nof_neighbours=%d\n", - cell_idx, serving_cell->earfcn, serving_cell->phy_cell.id, neighbour_cells.size()); + cell_idx, serving_cell->get_earfcn(), serving_cell->phy_cell.id, neighbour_cells.size()); } else { rrc_log->error("Setting invalid serving cell idx %d\n", cell_idx); @@ -520,19 +523,19 @@ void rrc::select_next_cell_in_plmn() { neighbour_cells[i]->in_sync) // matches S criteria { // Try to select Cell - if (phy->cell_select(neighbour_cells[i]->earfcn, neighbour_cells[i]->phy_cell)) { + if (phy->cell_select(neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->phy_cell)) { set_serving_cell(i); rrc_log->info("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", - serving_cell->phy_cell.id, serving_cell->earfcn, - serving_cell->sib1.cell_id); + serving_cell->phy_cell.id, serving_cell->get_earfcn(), + serving_cell->get_cell_id()); rrc_log->console("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", - serving_cell->phy_cell.id, serving_cell->earfcn, - serving_cell->sib1.cell_id); + serving_cell->phy_cell.id, serving_cell->get_earfcn(), + serving_cell->get_cell_id()); } else { // Set to out-of-sync if can't synchronize neighbour_cells[i]->in_sync = false; rrc_log->warning("Selecting cell EARFCN=%d, Cell ID=0x%x.\n", - neighbour_cells[i]->earfcn, neighbour_cells[i]->sib1.cell_id); + neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->get_cell_id()); } return; } @@ -543,7 +546,7 @@ void rrc::select_next_cell_in_plmn() { void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int pci_i) { if (earfcn_i < 0 || pci_i < 0) { - earfcn_i = serving_cell->earfcn; + earfcn_i = serving_cell->get_earfcn(); pci_i = serving_cell->phy_cell.id; } @@ -560,7 +563,7 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p // Update serving cell if (serving_cell->equals(earfcn, pci)) { cell_reselection_eval(rsrp, rsrq); - serving_cell->rsrp = rsrp; + serving_cell->set_rsrp(rsrp); rrc_log->info("MEAS: New measurement serving cell in IDLE, rsrp=%f, rsrq=%f, tti=%d\n", rsrp, rsrq, tti); // Or update/add neighbour cell @@ -573,13 +576,13 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p } // Verify cell selection criteria with strongest neighbour cell (always first) - if (cell_selection_eval(neighbour_cells[0]->rsrp) && - neighbour_cells[0]->rsrp > serving_cell->rsrp + 5) + if (cell_selection_eval(neighbour_cells[0]->get_rsrp()) && + neighbour_cells[0]->get_rsrp() > serving_cell->get_rsrp() + 5) { set_serving_cell(0); - rrc_log->info("Selecting best neighbour cell PCI=%d, rsrp=%.1f dBm\n", serving_cell->phy_cell.id, serving_cell->rsrp); + rrc_log->info("Selecting best neighbour cell PCI=%d, rsrp=%.1f dBm\n", serving_cell->phy_cell.id, serving_cell->get_rsrp()); state = RRC_STATE_CELL_SELECTING; - phy->cell_select(serving_cell->earfcn, serving_cell->phy_cell); + phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); } } } @@ -590,7 +593,7 @@ void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { int cell_idx = -1; if (serving_cell->equals(earfcn, phy_cell.id)) { - serving_cell->rsrp = rsrp; + serving_cell->set_rsrp(rsrp); serving_cell->in_sync = true; found = true; } else { @@ -598,18 +601,18 @@ void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { cell_idx = find_neighbour_cell(earfcn, phy_cell.id); if (cell_idx >= 0) { set_serving_cell(cell_idx); - serving_cell->rsrp = rsrp; + serving_cell->set_rsrp(rsrp); serving_cell->in_sync = true; found = true; } } if (found) { - if (!serving_cell->has_valid_sib1) { + if (!serving_cell->has_sib1()) { si_acquire_state = SI_ACQUIRE_SIB1; } else if (state == RRC_STATE_PLMN_SELECTION) { - for (uint32_t j = 0; j < serving_cell->sib1.N_plmn_ids; j++) { - nas->plmn_found(serving_cell->sib1.plmn_id[j].id, serving_cell->sib1.tracking_area_code); + for (uint32_t j = 0; j < serving_cell->sib1ptr()->N_plmn_ids; j++) { + nas->plmn_found(serving_cell->sib1ptr()->plmn_id[j].id, serving_cell->sib1ptr()->tracking_area_code); } usleep(5000); phy->cell_search_next(); @@ -631,22 +634,54 @@ void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { rrc_log->info("%s %s cell EARFCN=%d, PCI=%d, RSRP=%.1f dBm\n", found?"Updating":"Adding", cell_idx>=0?"neighbour":"serving", - serving_cell->earfcn, + serving_cell->get_earfcn(), serving_cell->phy_cell.id, - serving_cell->rsrp); + serving_cell->get_rsrp()); } bool sort_rsrp(cell_t *u1, cell_t *u2) { - return !u1->greater(u2); + return u1->greater(u2); } -// Sort neighbour cells by decreasing order of RSRP -void rrc::sort_neighbour_cells() { +void rrc::delete_neighbour(uint32_t cell_idx) { + measurements.delete_report(neighbour_cells[cell_idx]->get_earfcn(), neighbour_cells[cell_idx]->get_pci()); + delete neighbour_cells[cell_idx]; + neighbour_cells.erase(std::remove(neighbour_cells.begin(), neighbour_cells.end(), neighbour_cells[cell_idx]), neighbour_cells.end()); +} - for (uint32_t i=1;iin_sync == false) { - rrc_log->info("Removing neighbour cell PCI=%d, out_of_sync\n", neighbour_cells[i]->phy_cell.id); - neighbour_cells.erase(std::remove(neighbour_cells.begin(), neighbour_cells.end(), neighbour_cells[i]), neighbour_cells.end()); +std::vector::iterator rrc::delete_neighbour(std::vector::iterator it) { + measurements.delete_report((*it)->get_earfcn(), (*it)->get_pci()); + delete (*it); + return neighbour_cells.erase(it); +} + +void rrc::clean_neighbours() +{ + struct timeval now; + gettimeofday(&now, NULL); + + std::vector::iterator it = neighbour_cells.begin(); + while(it != neighbour_cells.end()) { + if ((*it)->timeout_secs(now) > NEIGHBOUR_TIMEOUT) { + rrc_log->info("Neighbour PCI=%d timed out. Deleting\n", (*it)->get_pci()); + it = delete_neighbour(it); + } else { + ++it; + } + } +} + +// Sort neighbour cells by decreasing order of RSRP +void rrc::sort_neighbour_cells() +{ + // Remove out-of-sync cells + std::vector::iterator it = neighbour_cells.begin(); + while(it != neighbour_cells.end()) { + if ((*it)->in_sync == false) { + rrc_log->info("Neighbour PCI=%d is out-of-sync. Deleting\n", (*it)->get_pci()); + it = delete_neighbour(it); + } else { + ++it; } } @@ -654,28 +689,27 @@ void rrc::sort_neighbour_cells() { char ordered[512]; int n=0; - n += snprintf(ordered, 512, "[pci=%d, rsrsp=%.2f", neighbour_cells[0]->phy_cell.id, neighbour_cells[0]->rsrp); + n += snprintf(ordered, 512, "[pci=%d, rsrsp=%.2f", neighbour_cells[0]->phy_cell.id, neighbour_cells[0]->get_rsrp()); for (uint32_t i=1;iphy_cell.id, neighbour_cells[i]->rsrp); + n += snprintf(&ordered[n], 512-n, " | pci=%d, rsrp=%.2f", neighbour_cells[i]->get_pci(), neighbour_cells[i]->get_rsrp()); } - rrc_log->info("Sorted neighbour cells: %s]\n", ordered); + rrc_log->info("Neighbours: %s]\n", ordered); } bool rrc::add_neighbour_cell(cell_t *new_cell) { bool ret = false; - if (neighbour_cells.size() < NOF_NEIGHBOUR_CELLS - 1) { + if (neighbour_cells.size() < NOF_NEIGHBOUR_CELLS) { ret = true; - } else if (!neighbour_cells[neighbour_cells.size()-1]->greater(new_cell)) { - // Delete old one - delete neighbour_cells[neighbour_cells.size()-1]; - neighbour_cells.erase(std::remove(neighbour_cells.begin(), neighbour_cells.end(), neighbour_cells[neighbour_cells.size()-1]), neighbour_cells.end()); + } else if (new_cell->greater(neighbour_cells[neighbour_cells.size()-1])) { + // Replace old one by new one + delete_neighbour(neighbour_cells.size()-1); ret = true; } if (ret) { neighbour_cells.push_back(new_cell); } rrc_log->info("Added neighbour cell EARFCN=%d, PCI=%d, nof_neighbours=%d\n", - new_cell->earfcn, new_cell->phy_cell.id, neighbour_cells.size()); + new_cell->get_earfcn(), new_cell->get_pci(), neighbour_cells.size()); sort_neighbour_cells(); return ret; } @@ -690,7 +724,7 @@ bool rrc::add_neighbour_cell(uint32_t earfcn, uint32_t pci, float rsrp) { bool rrc::add_neighbour_cell(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { if (earfcn == 0) { - earfcn = serving_cell->earfcn; + earfcn = serving_cell->get_earfcn(); } // First check if already exists @@ -700,7 +734,7 @@ bool rrc::add_neighbour_cell(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp // If exists, update RSRP, sort again and return if (cell_idx >= 0) { - neighbour_cells[cell_idx]->rsrp = rsrp; + neighbour_cells[cell_idx]->set_rsrp(rsrp); sort_neighbour_cells(); return true; } @@ -929,7 +963,7 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause, uint8_t *msg_ptr = varShortMAC; // ASN.1 encode byte-aligned VarShortMAC-Input - liblte_rrc_pack_cell_identity_ie(serving_cell->sib1.cell_id, &msg_ptr); + liblte_rrc_pack_cell_identity_ie(serving_cell->get_cell_id(), &msg_ptr); msg_ptr = &varShortMAC[4]; liblte_rrc_pack_phys_cell_id_ie(phy->get_current_pci(), &msg_ptr); msg_ptr = &varShortMAC[4+2]; @@ -937,7 +971,7 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause, srslte_bit_pack_vector(varShortMAC, varShortMAC_packed, (4+2+4)*8); rrc_log->info("Generated varShortMAC: cellId=0x%x, PCI=%d, rnti=%d\n", - serving_cell->sib1.cell_id, phy->get_current_pci(), crnti); + serving_cell->get_cell_id(), phy->get_current_pci(), crnti); // Compute MAC-I uint8_t mac_key[4]; @@ -1065,10 +1099,10 @@ bool rrc::ho_prepare() { if (pending_mob_reconf) { rrc_log->info("Processing HO command to target PCell=%d\n", mob_reconf.mob_ctrl_info.target_pci); - int target_cell_idx = find_neighbour_cell(serving_cell->earfcn, mob_reconf.mob_ctrl_info.target_pci); + int target_cell_idx = find_neighbour_cell(serving_cell->get_earfcn(), mob_reconf.mob_ctrl_info.target_pci); if (target_cell_idx < 0) { rrc_log->console("Received HO command to unknown PCI=%d\n", mob_reconf.mob_ctrl_info.target_pci); - rrc_log->error("Could not find target cell earfcn=%d, pci=%d\n", serving_cell->earfcn, mob_reconf.mob_ctrl_info.target_pci); + rrc_log->error("Could not find target cell earfcn=%d, pci=%d\n", serving_cell->get_earfcn(), mob_reconf.mob_ctrl_info.target_pci); return false; } @@ -1076,7 +1110,7 @@ bool rrc::ho_prepare() { mac_timers->timer_get(t310)->stop(); mac_timers->timer_get(t304)->set(this, liblte_rrc_t304_num[mob_reconf.mob_ctrl_info.t304]); if (mob_reconf.mob_ctrl_info.carrier_freq_eutra_present && - mob_reconf.mob_ctrl_info.carrier_freq_eutra.dl_carrier_freq != serving_cell->earfcn) { + mob_reconf.mob_ctrl_info.carrier_freq_eutra.dl_carrier_freq != serving_cell->get_earfcn()) { rrc_log->warning("Received mobilityControlInfo for inter-frequency handover\n"); } @@ -1099,9 +1133,9 @@ bool rrc::ho_prepare() { mac->set_ho_rnti(mob_reconf.mob_ctrl_info.new_ue_id, mob_reconf.mob_ctrl_info.target_pci); apply_rr_config_common_dl(&mob_reconf.mob_ctrl_info.rr_cnfg_common); - rrc_log->info("Selecting new cell pci=%d\n", neighbour_cells[target_cell_idx]->phy_cell.id); + rrc_log->info("Selecting new cell pci=%d\n", neighbour_cells[target_cell_idx]->get_pci()); if (!phy->cell_handover(neighbour_cells[target_cell_idx]->phy_cell)) { - rrc_log->error("Could not synchronize with target cell pci=%d\n", neighbour_cells[target_cell_idx]->phy_cell.id); + rrc_log->error("Could not synchronize with target cell pci=%d\n", neighbour_cells[target_cell_idx]->get_pci()); return false; } @@ -1177,7 +1211,7 @@ void rrc::ho_failed() { // Instruct PHY to resync with source PCI if (!phy->cell_handover(ho_src_cell.phy_cell)) { - rrc_log->error("Could not synchronize with target cell pci=%d\n", ho_src_cell.phy_cell.id); + rrc_log->error("Could not synchronize with target cell pci=%d\n", ho_src_cell.get_pci()); return; } @@ -1302,27 +1336,23 @@ void rrc::write_pdu_bcch_dlsch(byte_buffer_t *pdu) { rrc_log->info("Processing SIB: %d\n", liblte_rrc_sys_info_block_type_num[dlsch_msg.sibs[i].sib_type]); if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1 == dlsch_msg.sibs[i].sib_type && SI_ACQUIRE_SIB1 == si_acquire_state) { - memcpy(&serving_cell->sib1, &dlsch_msg.sibs[i].sib.sib1, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT)); - serving_cell->has_valid_sib1 = true; + serving_cell->set_sib1(&dlsch_msg.sibs[i].sib.sib1); handle_sib1(); - } else if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2 == dlsch_msg.sibs[i].sib_type && !serving_cell->has_valid_sib2) { - memcpy(&serving_cell->sib2, &dlsch_msg.sibs[i].sib.sib2, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT)); - serving_cell->has_valid_sib2 = true; + } else if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2 == dlsch_msg.sibs[i].sib_type && !serving_cell->has_sib2()) { + serving_cell->set_sib2(&dlsch_msg.sibs[i].sib.sib2); handle_sib2(); - } else if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3 == dlsch_msg.sibs[i].sib_type && !serving_cell->has_valid_sib3) { - memcpy(&serving_cell->sib3, &dlsch_msg.sibs[i].sib.sib3, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3_STRUCT)); - serving_cell->has_valid_sib3 = true; + } else if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3 == dlsch_msg.sibs[i].sib_type && !serving_cell->has_sib3()) { + serving_cell->set_sib3(&dlsch_msg.sibs[i].sib.sib3); handle_sib3(); - }else if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13 == dlsch_msg.sibs[i].sib_type && !serving_cell->has_valid_sib13) { - memcpy(&serving_cell->sib13, &dlsch_msg.sibs[0].sib.sib13, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13_STRUCT)); - serving_cell->has_valid_sib13 = true; + }else if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13 == dlsch_msg.sibs[i].sib_type && !serving_cell->has_sib13()) { + serving_cell->set_sib13(&dlsch_msg.sibs[i].sib.sib13); handle_sib13(); } } last_win_start = 0; - if(serving_cell->has_valid_sib2) { + if(serving_cell->has_sib2()) { sysinfo_index++; } } @@ -1330,16 +1360,16 @@ void rrc::write_pdu_bcch_dlsch(byte_buffer_t *pdu) { void rrc::handle_sib1() { rrc_log->info("SIB1 received, CellID=%d, si_window=%d, sib2_period=%d\n", - serving_cell->sib1.cell_id&0xfff, - liblte_rrc_si_window_length_num[serving_cell->sib1.si_window_length], - liblte_rrc_si_periodicity_num[serving_cell->sib1.sched_info[0].si_periodicity]); + serving_cell->get_cell_id()&0xfff, + liblte_rrc_si_window_length_num[serving_cell->sib1ptr()->si_window_length], + liblte_rrc_si_periodicity_num[serving_cell->sib1ptr()->sched_info[0].si_periodicity]); // Print SIB scheduling info uint32_t i,j; - for(i=0;isib1.N_sched_info;i++){ - for(j=0;jsib1.sched_info[i].N_sib_mapping_info;j++){ - LIBLTE_RRC_SIB_TYPE_ENUM t = serving_cell->sib1.sched_info[i].sib_mapping_info[j].sib_type; - LIBLTE_RRC_SI_PERIODICITY_ENUM p = serving_cell->sib1.sched_info[i].si_periodicity; + for(i=0;isib1ptr()->N_sched_info;i++){ + for(j=0;jsib1ptr()->sched_info[i].N_sib_mapping_info;j++){ + LIBLTE_RRC_SIB_TYPE_ENUM t = serving_cell->sib1ptr()->sched_info[i].sib_mapping_info[j].sib_type; + LIBLTE_RRC_SI_PERIODICITY_ENUM p = serving_cell->sib1ptr()->sched_info[i].si_periodicity; rrc_log->debug("SIB scheduling info, sib_type=%d, si_periodicity=%d\n", liblte_rrc_sib_type_num[t], liblte_rrc_si_periodicity_num[p]); @@ -1347,16 +1377,14 @@ void rrc::handle_sib1() } // Set TDD Config - if(serving_cell->sib1.tdd) { - phy->set_config_tdd(&serving_cell->sib1.tdd_cnfg); + if(serving_cell->sib1ptr()->tdd) { + phy->set_config_tdd(&serving_cell->sib1ptr()->tdd_cnfg); } - serving_cell->has_valid_sib1 = true; - // Send PLMN and TAC to NAS std::stringstream ss; - for (uint32_t i = 0; i < serving_cell->sib1.N_plmn_ids; i++) { - nas->plmn_found(serving_cell->sib1.plmn_id[i].id, serving_cell->sib1.tracking_area_code); + for (uint32_t i = 0; i < serving_cell->sib1ptr()->N_plmn_ids; i++) { + nas->plmn_found(serving_cell->sib1ptr()->plmn_id[i].id, serving_cell->sib1ptr()->tracking_area_code); } // Jump to next state @@ -1379,7 +1407,7 @@ void rrc::handle_sib2() { rrc_log->info("SIB2 received\n"); - apply_sib2_configs(&serving_cell->sib2); + apply_sib2_configs(serving_cell->sib2ptr()); } @@ -1387,7 +1415,7 @@ void rrc::handle_sib3() { rrc_log->info("SIB3 received\n"); - LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3_STRUCT *sib3 = &serving_cell->sib3; + LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3_STRUCT *sib3 = serving_cell->sib3ptr(); // cellReselectionInfoCommon cell_resel_cfg.q_hyst = liblte_rrc_q_hyst_num[sib3->q_hyst]; @@ -1699,7 +1727,7 @@ void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) { * *******************************************************************************/ void rrc::enable_capabilities() { - bool enable_ul_64 = args.ue_category >= 5 && serving_cell->sib2.rr_config_common_sib.pusch_cnfg.enable_64_qam; + bool enable_ul_64 = args.ue_category >= 5 && serving_cell->sib2ptr()->rr_config_common_sib.pusch_cnfg.enable_64_qam; rrc_log->info("%s 64QAM PUSCH\n", enable_ul_64 ? "Enabling" : "Disabling"); phy->set_config_64qam_en(enable_ul_64); } @@ -2373,28 +2401,45 @@ void rrc::rrc_meas::new_phy_meas(uint32_t earfcn, uint32_t pci, float rsrp, floa L3_filter(&pcell_measurement, values); // Update serving cell measurement - parent->serving_cell->rsrp = rsrp; + parent->serving_cell->set_rsrp(rsrp); } else { // Add to list of neighbour cells - parent->add_neighbour_cell(earfcn, pci, rsrp); - - log_h->info("MEAS: New measurement earfcn=%d, pci=%d, rsrp=%f, rsrq=%f, tti=%d\n", earfcn, pci, rsrp, rsrq, tti); - - // Save PHY measurement for all active measurements whose earfcn/pci matches - for(std::map::iterator iter=active.begin(); iter!=active.end(); ++iter) { - meas_t *m = &iter->second; - if (objects[m->object_id].earfcn == earfcn) { - // If it's a newly discovered cell, add it to objects - if (!m->cell_values.count(pci)) { - uint32_t cell_idx = objects[m->object_id].cells.size(); - objects[m->object_id].cells[cell_idx].pci = pci; - objects[m->object_id].cells[cell_idx].q_offset = 0; + bool added = parent->add_neighbour_cell(earfcn, pci, rsrp); + + log_h->info("MEAS: New measurement %s earfcn=%d, pci=%d, rsrp=%f, rsrq=%f, tti=%d\n", + added?"added":"not added", earfcn, pci, rsrp, rsrq, tti); + + // Only report measurements of 8th strongest cells + if (added) { + // Save PHY measurement for all active measurements whose earfcn/pci matches + for(std::map::iterator iter=active.begin(); iter!=active.end(); ++iter) { + meas_t *m = &iter->second; + if (objects[m->object_id].earfcn == earfcn) { + // If it's a newly discovered cell, add it to objects + if (!m->cell_values.count(pci)) { + uint32_t cell_idx = objects[m->object_id].cells.size(); + objects[m->object_id].cells[cell_idx].pci = pci; + objects[m->object_id].cells[cell_idx].q_offset = 0; + } + // Update or add cell + L3_filter(&m->cell_values[pci], values); + return; } - // Update or add cell - L3_filter(&m->cell_values[pci], values); - return; + } + } + } +} + +// Remove all stored measurements for a given cell +void rrc::rrc_meas::delete_report(uint32_t earfcn, uint32_t pci) { + for(std::map::iterator iter=active.begin(); iter!=active.end(); ++iter) { + meas_t *m = &iter->second; + if (objects[m->object_id].earfcn == earfcn) { + if (m->cell_values.count(pci)) { + m->cell_values.erase(pci); + log_h->info("Deleting report PCI=%d from cell_values\n", pci); } } } From 9c416aa97e22130821d0a6562129f965ded905e4 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 23 Feb 2018 13:15:01 +0100 Subject: [PATCH 127/342] Disable RSSI sensor by default and expose rx_gain for calibration --- srsue/src/main.cc | 4 ++-- srsue/src/upper/rrc.cc | 2 +- srsue/ue.conf.example | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/srsue/src/main.cc b/srsue/src/main.cc index e76891796..1cac2092d 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -159,11 +159,11 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { "Pregenerate uplink signals after attach. Improves CPU performance.") ("expert.rssi_sensor_enabled", - bpo::value(&args->expert.phy.rssi_sensor_enabled)->default_value(true), + bpo::value(&args->expert.phy.rssi_sensor_enabled)->default_value(false), "Enable or disable RF frontend RSSI sensor. In some USRP devices can cause segmentation fault") ("expert.rx_gain_offset", - bpo::value(&args->expert.phy.rx_gain_offset)->default_value(10), + bpo::value(&args->expert.phy.rx_gain_offset)->default_value(62), "RX Gain offset to add to rx_gain to correct RSRP value") ("expert.prach_gain", diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 9e26436ae..6809eea4f 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -389,7 +389,7 @@ void rrc::run_si_acquisition_procedure() last_win_start = si_win_start; mac->bcch_start_rx(si_win_start, si_win_len); - rrc_log->info("Instructed MAC to search for system info, win_start=%d, win_len=%d\n", + rrc_log->debug("Instructed MAC to search for system info, win_start=%d, win_len=%d\n", si_win_start, si_win_len); } diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 2b8da9643..5e6f01027 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -118,6 +118,7 @@ enable = false # ip_netmask: Netmask of the tun_srsue device. Default: 255.255.255.0 # rssi_sensor_enabled: Enable or disable RF frontend RSSI sensor. Required for RSRP metrics but # can cause UHD instability for long-duration testing. Default true. +# rx_gain_offset: RX Gain offset to add to rx_gain to calibrate RSRP readings # prach_gain: PRACH gain (dB). If defined, forces a gain for the tranmsission of PRACH only., # Default is to use tx_gain in [rf] section. # cqi_max: Upper bound on the maximum CQI to be reported. Default 15. @@ -176,6 +177,7 @@ enable = false [expert] #ip_netmask = 255.255.255.0 #rssi_sensor_enabled = false +#rx_gain_offset = 62 #prach_gain = 30 #cqi_max = 15 #cqi_fixed = 10 From aced809146ff2e1327829b288fd29cad059040f0 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sat, 24 Feb 2018 21:28:05 +0100 Subject: [PATCH 128/342] Set rx_gain_offset for B210 --- srsue/src/main.cc | 4 ++-- srsue/ue.conf.example | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/srsue/src/main.cc b/srsue/src/main.cc index e76891796..1cac2092d 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -159,11 +159,11 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { "Pregenerate uplink signals after attach. Improves CPU performance.") ("expert.rssi_sensor_enabled", - bpo::value(&args->expert.phy.rssi_sensor_enabled)->default_value(true), + bpo::value(&args->expert.phy.rssi_sensor_enabled)->default_value(false), "Enable or disable RF frontend RSSI sensor. In some USRP devices can cause segmentation fault") ("expert.rx_gain_offset", - bpo::value(&args->expert.phy.rx_gain_offset)->default_value(10), + bpo::value(&args->expert.phy.rx_gain_offset)->default_value(62), "RX Gain offset to add to rx_gain to correct RSRP value") ("expert.prach_gain", diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 2b8da9643..b8cc43c2e 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -118,6 +118,7 @@ enable = false # ip_netmask: Netmask of the tun_srsue device. Default: 255.255.255.0 # rssi_sensor_enabled: Enable or disable RF frontend RSSI sensor. Required for RSRP metrics but # can cause UHD instability for long-duration testing. Default true. +# rx_gain_offset: RX Gain offset to add to rx_gain to calibrate RSRP readings # prach_gain: PRACH gain (dB). If defined, forces a gain for the tranmsission of PRACH only., # Default is to use tx_gain in [rf] section. # cqi_max: Upper bound on the maximum CQI to be reported. Default 15. @@ -176,6 +177,7 @@ enable = false [expert] #ip_netmask = 255.255.255.0 #rssi_sensor_enabled = false +#rx_gain_offset = 72 #prach_gain = 30 #cqi_max = 15 #cqi_fixed = 10 From 56455b31ef212286501f9f25b205259daeb2d6a9 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sat, 24 Feb 2018 21:29:57 +0100 Subject: [PATCH 129/342] Use dedicated thread for MAC timers --- srsue/hdr/mac/mac.h | 15 +++++++++++++-- srsue/hdr/mac/ul_harq.h | 1 - srsue/src/mac/mac.cc | 14 +++++++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/srsue/hdr/mac/mac.h b/srsue/hdr/mac/mac.h index e59aa8f16..f4b0ffe3a 100644 --- a/srsue/hdr/mac/mac.h +++ b/srsue/hdr/mac/mac.h @@ -162,13 +162,24 @@ private: void timer_alignment_expire(); srslte::timers timers; - // pointer to MAC PCAP object srslte::mac_pcap* pcap; bool is_first_ul_grant; + mac_metrics_t metrics; + + /* Class to run Timers in a dedicated thread */ + class mac_timers : public periodic_thread { + public: + void init(srslte::timers *timers, srslte::log *log_h); + private: + void run_period(); + srslte::timers *timers; + bool running; + srslte::log *log_h; + }; - mac_metrics_t metrics; + mac_timers mactimers; /* Class to process MAC PDUs from DEMUX unit */ class pdu_process : public thread { diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index 60deff36f..5c44a222e 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -246,7 +246,6 @@ private: } else { Warning("UL RAR grant available but no Msg3 on buffer\n"); } - printf("Transmitted Msg3\n"); // Normal UL grant } else { diff --git a/srsue/src/mac/mac.cc b/srsue/src/mac/mac.cc index daa82d1cb..2531faafc 100644 --- a/srsue/src/mac/mac.cc +++ b/srsue/src/mac/mac.cc @@ -82,6 +82,7 @@ bool mac::init(phy_interface_mac *phy, rlc_interface_mac *rlc, rrc_interface_mac started = true; start(MAC_MAIN_THREAD_PRIO); + mactimers.init(&timers, log_h); return started; } @@ -94,6 +95,7 @@ void mac::stop() ttisync.increase(); pdu_process_thread.stop(); wait_thread_finish(); + mactimers.stop(); } void mac::start_pcap(srslte::mac_pcap* pcap_) @@ -148,6 +150,17 @@ void mac::reset() bzero(&uernti, sizeof(ue_rnti_t)); } +void mac::mac_timers::init(srslte::timers *timers, srslte::log *log_h) { + this->timers = timers; + running = true; + this->log_h = log_h; + start_periodic(1000); +} + +void mac::mac_timers::run_period() { + timers->step_all(); +} + void mac::run_thread() { int cnt=0; @@ -165,7 +178,6 @@ void mac::run_thread() { tti = ttisync.wait(); log_h->step(tti); - timers.step_all(); // Step all procedures bsr_procedure.step(tti); From 42ece73453274f064b15ba450a59578397dbef35 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sat, 24 Feb 2018 21:33:13 +0100 Subject: [PATCH 130/342] Changed cell selection/reselection to avoid stopping/restarting radio. Fixed SIB message search --- srsue/hdr/phy/phch_recv.h | 3 +-- srsue/hdr/upper/rrc_common.h | 4 +++ srsue/src/phy/phch_recv.cc | 51 ++++++++++++++++++++---------------- srsue/src/upper/nas.cc | 5 +++- srsue/src/upper/rrc.cc | 35 ++++++++++++------------- 5 files changed, 54 insertions(+), 44 deletions(-) diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index bc7255ac9..a14f8e9fa 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -104,7 +104,7 @@ private: bool set_cell(); void cell_search_inc(); - void resync_sfn(bool is_connected = false, bool rx_now = false); + void resync_sfn(bool restart_radio, bool restart_now = false); bool stop_sync(); void stop_rx(); @@ -307,7 +307,6 @@ private: IDLE = 0, CELL_SEARCH, CELL_SELECT, - CELL_RESELECT, CELL_MEASURE, CELL_CAMP, IDLE_RX diff --git a/srsue/hdr/upper/rrc_common.h b/srsue/hdr/upper/rrc_common.h index 6d1186812..259d08fd7 100644 --- a/srsue/hdr/upper/rrc_common.h +++ b/srsue/hdr/upper/rrc_common.h @@ -33,6 +33,7 @@ namespace srsue { // RRC states (3GPP 36.331 v10.0.0) typedef enum { RRC_STATE_IDLE = 0, + RRC_STATE_PLMN_START, RRC_STATE_PLMN_SELECTION, RRC_STATE_CELL_SELECTING, RRC_STATE_CELL_SELECTED, @@ -44,11 +45,14 @@ typedef enum { RRC_STATE_N_ITEMS, } rrc_state_t; static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE", + "PLMN SELECTED", "PLMN SELECTION", "CELL SELECTING", "CELL SELECTED", "CONNECTING", "CONNECTED", + "HO PREPARE", + "HO PROCESS", "LEAVE CONNECTED"}; } // namespace srsue diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 5e2ec4dee..4a8fef5bf 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -265,17 +265,22 @@ bool phch_recv::set_cell() { return cell_is_set; } -void phch_recv::resync_sfn(bool is_connected, bool now) { +void phch_recv::resync_sfn(bool restart_radio, bool restart_now) { - if (!now) { + if (restart_radio) { wait_radio_reset(); stop_rx(); + usleep(100000); } - start_rx(now); sfn_p.reset(); - Info("SYNC: Starting SFN synchronization\n"); + search_p.reset(); + srslte_ue_sync_reset(&ue_sync); - phy_state = is_connected?CELL_RESELECT:CELL_SELECT; + if (restart_radio) { + start_rx(restart_now); + } + + phy_state = CELL_SELECT; } void phch_recv::set_earfcn(std::vector earfcn) { @@ -294,7 +299,7 @@ bool phch_recv::stop_sync() { if (phy_state == IDLE && is_in_idle) { return true; } else { - Info("SYNC: Going to IDLE\n"); + Info("SYNC: Going to IDLE (state=%d)\n", phy_state); phy_state = IDLE; int cnt = 0; while (!is_in_idle && cnt < 100) { @@ -302,7 +307,7 @@ bool phch_recv::stop_sync() { cnt++; } if (!is_in_idle) { - Warning("SYNC: Could not go to IDLE\n"); + Warning("SYNC: Could not go to IDLE (state=%d)\n", phy_state); } return is_in_idle; } @@ -310,11 +315,12 @@ bool phch_recv::stop_sync() { void phch_recv::reset_sync() { - Warning("SYNC: Resetting sync, cell_search_in_progress=%s\n", cell_search_in_progress?"yes":"no"); - - search_p.reset(); - srslte_ue_sync_reset(&ue_sync); - resync_sfn(true, true); + if (phy_state != CELL_SELECT) { + Warning("SYNC: Resetting sync, cell_search_in_progress=%s\n", cell_search_in_progress?"yes":"no"); + resync_sfn(false); + } else { + Warning("SYNC: Trying to reset sync while in cell reselection\n"); + } } void phch_recv::cell_search_inc() @@ -323,6 +329,8 @@ void phch_recv::cell_search_inc() if (cur_earfcn_index >= 0) { if (cur_earfcn_index >= (int) earfcn.size()) { cur_earfcn_index = 0; + cell_search_in_progress = false; + phy_state = IDLE; rrc->earfcn_end(); } else { Info("SYNC: Cell Search idx %d/%d\n", cur_earfcn_index, earfcn.size()); @@ -338,7 +346,7 @@ void phch_recv::cell_search_next(bool reset) { if (cell_search_in_progress || reset) { cell_search_in_progress = false; if (!stop_sync()) { - log_h->warning("SYNC: Couldn't stop PHY\n"); + log_h->warning("SYNC: Couldn't stop PHY (state=%d)\n", phy_state); } if (reset) { cur_earfcn_index = -1; @@ -393,9 +401,7 @@ bool phch_recv::cell_handover(srslte_cell_t cell) if (is_in_idle_rx) { Info("Cell HO: Reconfiguring cell\n"); if (set_cell()) { - //resync_sfn(true, true); - sfn_p.reset(); - phy_state = CELL_RESELECT; + resync_sfn(false); Info("Cell HO: Synchronizing with new cell\n"); ret = true; } else { @@ -419,7 +425,7 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { set_sampling_rate(); } if (phy_state < CELL_SELECT) { - resync_sfn(); + resync_sfn(true, false); } return true; } else { @@ -444,9 +450,7 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { if (set_cell()) { log_h->info("Cell Select: Synchronizing on cell...\n"); - resync_sfn(); - - usleep(500000); // Time offset we set start_rx to start receiving samples + resync_sfn(true, false); return true; } return false; @@ -616,13 +620,14 @@ void phch_recv::run_thread() } if (set_cell()) { set_sampling_rate(); - resync_sfn(); + resync_sfn(true, false); } break; case search::CELL_NOT_FOUND: if (cell_search_in_progress) { cell_search_inc(); } + phy_state = IDLE; break; default: radio_error(); @@ -630,7 +635,6 @@ void phch_recv::run_thread() } } break; - case CELL_RESELECT: case CELL_SELECT: switch (sfn_p.run_subframe(&cell, &tti)) { @@ -650,7 +654,7 @@ void phch_recv::run_thread() phy_state = CELL_SEARCH; } else { log_h->warning("SYNC: Timeout while synchronizing SFN. Reselecting cell\n"); - resync_sfn(true, true); + resync_sfn(false); } break; case sfn_sync::IDLE: @@ -666,6 +670,7 @@ void phch_recv::run_thread() case measure::MEASURE_OK: log_h->info("SYNC: Measured OK. Camping on cell PCI=%d...\n", cell.id); phy_state = CELL_CAMP; + cell_search_in_progress = false; rrc->cell_found(earfcn[cur_earfcn_index], cell, measure_p.rsrp()); break; case measure::IDLE: diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 04b5f4869..7f5683867 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -171,7 +171,10 @@ void nas::plmn_search_end() { rrc->plmn_select(known_plmns[0]); } else { - nas_log->debug("Finished searching PLMN in current EARFCN set but no networks were found.\n"); + nas_log->info("Finished searching PLMN in current EARFCN set but no networks were found.\n"); + if (state == EMM_STATE_REGISTERED_INITIATED && plmn_selection == PLMN_NOT_SELECTED) { + rrc->plmn_search(); + } } } diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 9e26436ae..0760ccb7e 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -202,6 +202,12 @@ void rrc::run_thread() { // If not attached, PLMN selection will be triggered from higher layers } break; + case RRC_STATE_PLMN_START: + rrc_log->info("RRC PLMN Search: Starting cell search\n"); + plmn_select_timeout = 0; + phy->cell_search_start(); + state = RRC_STATE_PLMN_SELECTION; + break; case RRC_STATE_PLMN_SELECTION: plmn_select_timeout++; if (plmn_select_timeout >= RRC_PLMN_SELECT_TIMEOUT) { @@ -209,8 +215,7 @@ void rrc::run_thread() { phy->cell_search_stop(); sleep(1); rrc_log->console("\nRRC PLMN Search: timeout expired. Searching again\n"); - plmn_select_timeout = 0; - phy->cell_search_start(); + } break; case RRC_STATE_CELL_SELECTING: @@ -230,7 +235,7 @@ void rrc::run_thread() { state = RRC_STATE_CELL_SELECTED; } } - // Don't time out during restablishment (T311 running) + // Don't time out during reestablishment (T311 running) if (!mac_timers->timer_get(t311)->is_running()) { select_cell_timeout++; if (select_cell_timeout >= RRC_SELECT_CELL_TIMEOUT) { @@ -351,7 +356,7 @@ void rrc::run_si_acquisition_procedure() tti = mac->get_current_tti(); si_win_start = sib_start_tti(tti, 2, 0, 5); if (last_win_start == 0 || - (srslte_tti_interval(last_win_start, tti) > 20 && srslte_tti_interval(last_win_start, tti) < 1000)) + (srslte_tti_interval(tti, last_win_start) >= 20 && srslte_tti_interval(tti, last_win_start) < 1000)) { last_win_start = si_win_start; @@ -384,12 +389,12 @@ void rrc::run_si_acquisition_procedure() si_win_len = liblte_rrc_si_window_length_num[serving_cell->sib1ptr()->si_window_length]; if (last_win_start == 0 || - (srslte_tti_interval(last_win_start, tti) > period*10 && srslte_tti_interval(last_win_start, tti) < 1000)) + (srslte_tti_interval(tti, last_win_start) > period*10 && srslte_tti_interval(tti, last_win_start) < 1000)) { last_win_start = si_win_start; mac->bcch_start_rx(si_win_start, si_win_len); - rrc_log->info("Instructed MAC to search for system info, win_start=%d, win_len=%d\n", + rrc_log->debug("Instructed MAC to search for system info, win_start=%d, win_len=%d\n", si_win_start, si_win_len); } @@ -433,10 +438,7 @@ uint16_t rrc::get_mnc() { } void rrc::plmn_search() { - rrc_log->info("Starting PLMN search procedure\n"); - state = RRC_STATE_PLMN_SELECTION; - phy->cell_search_start(); - plmn_select_timeout = 0; + state = RRC_STATE_PLMN_START; } /* This is the NAS interface. When NAS requests to select a PLMN we have to @@ -576,7 +578,8 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p } // Verify cell selection criteria with strongest neighbour cell (always first) - if (cell_selection_eval(neighbour_cells[0]->get_rsrp()) && + if (neighbour_cells.size() > 1 && + cell_selection_eval(neighbour_cells[0]->get_rsrp()) && neighbour_cells[0]->get_rsrp() > serving_cell->get_rsrp() + 5) { set_serving_cell(0); @@ -761,10 +764,6 @@ void rrc::earfcn_end() { // If searching for PLMN, indicate NAS we scanned all frequencies if (state == RRC_STATE_PLMN_SELECTION) { nas->plmn_search_end(); - } else if (state == RRC_STATE_CELL_SELECTING) { - select_cell_timeout = 0; - rrc_log->info("Starting cell search again\n"); - phy->cell_search_start(); } } @@ -825,11 +824,11 @@ void rrc::out_of_sync() { if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) { n310_cnt++; if (n310_cnt == N310) { + rrc_log->info("Detected %d out-of-sync from PHY. Trying to resync. Starting T310 timer %d ms\n", + N310, mac_timers->timer_get(t310)->get_timeout()); mac_timers->timer_get(t310)->reset(); mac_timers->timer_get(t310)->run(); n310_cnt = 0; - phy->sync_reset(); - rrc_log->info("Detected %d out-of-sync from PHY. Trying to resync. Starting T310 timer\n", N310); } } } else { @@ -856,7 +855,6 @@ void rrc::in_sync() { void rrc::radio_link_failure() { // TODO: Generate and store failure report - phy->sync_reset(); rrc_log->warning("Detected Radio-Link Failure\n"); rrc_log->console("Warning: Detected Radio-Link Failure\n"); if (state != RRC_STATE_CONNECTED) { @@ -1016,6 +1014,7 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause, set_phy_default(); mac->reset(); set_mac_default(); + phy->sync_reset(); state = RRC_STATE_CELL_SELECTING; } From df67735a99d256ff45df73bedfa12e8627fec57c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 25 Feb 2018 13:08:36 +0100 Subject: [PATCH 131/342] Reset UL after IDLEling PHY --- srsue/src/phy/phch_recv.cc | 11 ++++++++++- srsue/src/upper/rrc.cc | 3 ++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 4a8fef5bf..d63d298ec 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -391,13 +391,22 @@ bool phch_recv::cell_handover(srslte_cell_t cell) bool ret = false; this->cell = cell; Info("Cell HO: Stopping sync with current cell\n"); - worker_com->reset_ul(); phy_state = IDLE_RX; cnt = 0; while(!is_in_idle_rx && cnt<20) { usleep(1000); cnt++; } + cnt = 0; + while(!is_in_idle_rx && cnt<20) { + usleep(1000); + cnt++; + } + for(uint32_t i=0;iget_nof_workers();i++) { + ((phch_worker*) workers_pool->get_worker(i))->reset(); + } + worker_com->reset(); + worker_com->reset_ul(); if (is_in_idle_rx) { Info("Cell HO: Reconfiguring cell\n"); if (set_cell()) { diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 0760ccb7e..9c5ad52c1 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1128,7 +1128,8 @@ bool rrc::ho_prepare() { pdcp->reestablish(); rlc->reestablish(); mac->reset(); - phy->reset(); + // PHY is reset inside cell_handover() function + mac->set_ho_rnti(mob_reconf.mob_ctrl_info.new_ue_id, mob_reconf.mob_ctrl_info.target_pci); apply_rr_config_common_dl(&mob_reconf.mob_ctrl_info.rr_cnfg_common); From cfaa5e9b281e4bb501446a3d35f26ccf9a7cd4fc Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 25 Feb 2018 19:13:12 +0100 Subject: [PATCH 132/342] Fix previous commit could not HO more than once due to not refreshing serving cell after 1st HO --- lib/include/srslte/interfaces/ue_interfaces.h | 2 +- srsue/hdr/upper/rrc.h | 7 +++++-- srsue/src/phy/phch_recv.cc | 3 ++- srsue/src/upper/rrc.cc | 8 ++++---- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 00b61fa1c..f18a6737b 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -160,7 +160,7 @@ public: virtual void in_sync() = 0; virtual void out_of_sync() = 0; virtual void earfcn_end() = 0; - virtual void cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) = 0; + virtual void cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp = NAN) = 0; virtual void new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn = -1, int pci = -1) = 0; }; diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 5f269ec86..1bfae16b3 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -37,6 +37,7 @@ #include "srslte/common/security.h" #include "srslte/common/threads.h" +#include #include #include @@ -106,7 +107,9 @@ class cell_t } void set_rsrp(float rsrp) { - this->rsrp = rsrp; + if (~isnan(rsrp)) { + this->rsrp = rsrp; + } in_sync = true; gettimeofday(&last_update, NULL); } @@ -252,7 +255,7 @@ public: void in_sync(); void out_of_sync(); void earfcn_end(); - void cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp); + void cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp); void new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn, int pci); // MAC interface diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index d63d298ec..5701297c4 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -651,6 +651,7 @@ void phch_recv::run_thread() if (!cell_search_in_progress) { log_h->info("Sync OK. Camping on cell PCI=%d...\n", cell.id); phy_state = CELL_CAMP; + rrc->cell_camping(earfcn[cur_earfcn_index], cell); } else { log_h->info("Sync OK. Measuring PCI=%d...\n", cell.id); measure_p.reset(); @@ -680,7 +681,7 @@ void phch_recv::run_thread() log_h->info("SYNC: Measured OK. Camping on cell PCI=%d...\n", cell.id); phy_state = CELL_CAMP; cell_search_in_progress = false; - rrc->cell_found(earfcn[cur_earfcn_index], cell, measure_p.rsrp()); + rrc->cell_camping(earfcn[cur_earfcn_index], cell, measure_p.rsrp()); break; case measure::IDLE: break; diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 9c5ad52c1..dfb356b92 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -590,14 +590,16 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p } } -void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { +/* PHY begins camping in a cell. RRC updates RSRP measurement, + * proceeds with PLMN selection/cell search if applicable and sets + * new cell as current serving cell */ +void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { bool found = false; int cell_idx = -1; if (serving_cell->equals(earfcn, phy_cell.id)) { serving_cell->set_rsrp(rsrp); - serving_cell->in_sync = true; found = true; } else { // Check if cell is in our list of neighbour cells @@ -605,7 +607,6 @@ void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { if (cell_idx >= 0) { set_serving_cell(cell_idx); serving_cell->set_rsrp(rsrp); - serving_cell->in_sync = true; found = true; } } @@ -629,7 +630,6 @@ void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { phy->cell_search_next(); } else { set_serving_cell(earfcn, phy_cell.id); - si_acquire_state = SI_ACQUIRE_SIB1; } } From 65aa5abb309e2739af0725c86211a0ae6b6f8402 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 25 Feb 2018 20:51:16 +0100 Subject: [PATCH 133/342] Restored RSRP calculation changed in commit 3f002aca85f9a23226c3481b3619ae11ad798e94 --- lib/src/phy/ch_estimation/chest_dl.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index 5249696af..221bac319 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -540,22 +540,23 @@ 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); - q->rsrp[rxant_id][port_id] = srslte_vec_avg_power_cf(q->pilot_estimates, npilots); - q->rssi[rxant_id][port_id] = srslte_chest_dl_rssi(q, input, port_id); } int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id) { + uint32_t npilots = SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id); + /* Get references from the input signal */ srslte_refsignal_cs_get_sf(q->cell, port_id, input, q->pilot_recv_signal); /* Use the known CSR signal to compute Least-squares estimates */ srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->csr_refs.pilots[port_id/2][sf_idx], - q->pilot_estimates, SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id)); + q->pilot_estimates, npilots); + /* Compute RSRP for the channel estimates in this port */ + double energy = cabs(srslte_vec_acc_cc(q->pilot_estimates, npilots)/npilots); + q->rsrp[rxant_id][port_id] = energy*energy; + q->rssi[rxant_id][port_id] = srslte_chest_dl_rssi(q, input, port_id); chest_interpolate_noise_est(q, input, ce, sf_idx, port_id, rxant_id, SRSLTE_SF_NORM); From beccfd29195194857417e278b157e3bdb9747000 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 25 Feb 2018 23:36:08 +0100 Subject: [PATCH 134/342] Average RSRP in linear domain to get better resolution --- srsue/hdr/phy/phch_recv.h | 6 ++--- srsue/src/phy/phch_recv.cc | 50 ++++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index a14f8e9fa..1e15aea62 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -167,13 +167,14 @@ private: typedef enum {IDLE, MEASURE_OK, ERROR} ret_code; ~measure(); - void init(cf_t *buffer[SRSLTE_MAX_PORTS], srslte::log *log_h, srslte::radio *radio_h, + void init(cf_t *buffer[SRSLTE_MAX_PORTS], srslte::log *log_h, uint32_t nof_rx_antennas, uint32_t nof_subframes = RSRP_MEASURE_NOF_FRAMES); void reset(); void set_cell(srslte_cell_t cell); ret_code run_subframe(uint32_t sf_idx); ret_code run_subframe_sync(srslte_ue_sync_t *ue_sync, uint32_t sf_idx); ret_code run_multiple_subframes(cf_t *buffer, uint32_t offset, uint32_t sf_idx, uint32_t nof_sf); + float rssi(); float rsrp(); float rsrq(); float snr(); @@ -183,7 +184,6 @@ private: srslte::log *log_h; srslte_ue_dl_t ue_dl; cf_t *buffer[SRSLTE_MAX_PORTS]; - srslte::radio *radio_h; uint32_t cnt; uint32_t nof_subframes; uint32_t current_prb; @@ -235,7 +235,7 @@ private: void write(uint32_t tti, cf_t *data, uint32_t nsamples); private: void run_thread(); - const static int INTRA_FREQ_MEAS_LEN_MS = 20; + const static int INTRA_FREQ_MEAS_LEN_MS = 50; const static int INTRA_FREQ_MEAS_PERIOD_MS = 200; const static int INTRA_FREQ_MEAS_PRIO = DEFAULT_PRIORITY + 5; diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 5701297c4..6737f52e0 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -91,7 +91,7 @@ void phch_recv::init(srslte::radio_multi *_radio_handler, mac_interface_phy *_ma sfn_p.init(&ue_sync, sf_buffer, log_h); // Initialize measurement class for the primary cell - measure_p.init(sf_buffer, log_h, radio_h, nof_rx_antennas); + measure_p.init(sf_buffer, log_h, nof_rx_antennas); // Start intra-frequency measurement intra_freq_meas.init(worker_com, rrc, log_h); @@ -675,9 +675,18 @@ void phch_recv::run_thread() } break; case CELL_MEASURE: + switch(measure_p.run_subframe_sync(&ue_sync, sf_idx)) { case measure::MEASURE_OK: + + // Calibrate measure object since worker not yet calibrated + if (worker_com->args->rssi_sensor_enabled) { + measure_p.set_rx_gain_offset(measure_p.rssi() - radio_h->get_rssi() + 30); + } else { + measure_p.set_rx_gain_offset(worker_com->args->rx_gain_offset + radio_h->get_rx_gain()); + } + log_h->info("SYNC: Measured OK. Camping on cell PCI=%d...\n", cell.id); phy_state = CELL_CAMP; cell_search_in_progress = false; @@ -1095,11 +1104,10 @@ phch_recv::sfn_sync::ret_code phch_recv::sfn_sync::run_subframe(srslte_cell_t *c /********* * Measurement class */ -void phch_recv::measure::init(cf_t *buffer[SRSLTE_MAX_PORTS], srslte::log *log_h, srslte::radio *radio_h, uint32_t nof_rx_antennas, uint32_t nof_subframes) +void phch_recv::measure::init(cf_t *buffer[SRSLTE_MAX_PORTS], srslte::log *log_h, uint32_t nof_rx_antennas, uint32_t nof_subframes) { - this->radio_h = radio_h; - this->log_h = log_h; + this->log_h = log_h; this->nof_subframes = nof_subframes; for (int i=0;ibuffer[i] = buffer[i]; @@ -1132,17 +1140,21 @@ void phch_recv::measure::set_cell(srslte_cell_t cell) } reset(); } - + +float phch_recv::measure::rssi() { + return 10*log10(mean_rssi); +} + float phch_recv::measure::rsrp() { - return mean_rsrp; + return 10*log10(mean_rsrp) + 30 - rx_gain_offset; } float phch_recv::measure::rsrq() { - return mean_rsrq; + return 10*log10(mean_rsrq); } float phch_recv::measure::snr() { - return mean_snr; + return 10*log10(mean_snr); } uint32_t phch_recv::measure::frame_st_idx() { @@ -1243,10 +1255,10 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx) return ERROR; } - float rsrp = 10*log10(srslte_chest_dl_get_rsrp(&ue_dl.chest)) + 30 - rx_gain_offset; - float rsrq = 10*log10(srslte_chest_dl_get_rsrq(&ue_dl.chest)); - float snr = 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)); - float rssi = 10*log10(srslte_vec_avg_power_cf(buffer[0], SRSLTE_SF_LEN_PRB(current_prb))) + 30; + float rsrp = srslte_chest_dl_get_rsrp(&ue_dl.chest); + float rsrq = srslte_chest_dl_get_rsrq(&ue_dl.chest); + float snr = srslte_chest_dl_get_snr(&ue_dl.chest); + float rssi = srslte_vec_avg_power_cf(buffer[0], SRSLTE_SF_LEN_PRB(current_prb)); if (cnt == 0) { mean_rsrp = rsrp; @@ -1265,17 +1277,6 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx) cnt, nof_subframes, sf_idx, rsrp, snr); if (cnt >= nof_subframes) { - - // Calibrate RSRP if no gain offset measurements - if (fabsf(rx_gain_offset) < 1.0 && radio_h) { - float temporal_offset = 0; - if (radio_h->has_rssi()) { - temporal_offset = mean_rssi - radio_h->get_rssi() + 30; - } else { - temporal_offset = radio_h->get_rx_gain(); - } - mean_rsrp -= temporal_offset; - } return MEASURE_OK; } else { return IDLE; @@ -1304,7 +1305,7 @@ void phch_recv::scell_recv::init(srslte::log *log_h, bool sic_pss_enabled, uint3 sf_buffer[0] = (cf_t*) srslte_vec_malloc(sizeof(cf_t)*max_sf_size); input_cfo_corrected = (cf_t*) srslte_vec_malloc(sizeof(cf_t)*15*max_sf_size); - measure_p.init(sf_buffer, log_h, NULL, 1, max_sf_window); + measure_p.init(sf_buffer, log_h, 1, max_sf_window); //do this different we don't need all this search window. if(srslte_sync_init(&sync_find, max_sf_window*max_sf_size, 5*max_sf_size, max_fft_sz)) { @@ -1609,6 +1610,7 @@ void phch_recv::intra_measure::run_thread() } if (running) { + // Read data from buffer and find cells in it srslte_ringbuffer_read(&ring_buffer, search_buffer, INTRA_FREQ_MEAS_LEN_MS*current_sflen*sizeof(cf_t)); int found_cells = scell.find_cells(search_buffer, common->rx_gain_offset, primary_cell, INTRA_FREQ_MEAS_LEN_MS, info); From 669ef9816fdae1374ba3e4bfcab65eaa0571cffe Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 26 Feb 2018 10:39:40 +0000 Subject: [PATCH 135/342] Added packing of TMSI to mobile station identity IE. --- lib/include/srslte/asn1/liblte_mme.h | 1 + lib/src/asn1/liblte_mme.cc | 64 +++++++++++++++++++--------- srsepc/src/mme/s1ap_nas_transport.cc | 24 ++++++++--- 3 files changed, 62 insertions(+), 27 deletions(-) diff --git a/lib/include/srslte/asn1/liblte_mme.h b/lib/include/srslte/asn1/liblte_mme.h index 78e2cae69..85b8b2241 100644 --- a/lib/include/srslte/asn1/liblte_mme.h +++ b/lib/include/srslte/asn1/liblte_mme.h @@ -175,6 +175,7 @@ typedef struct{ uint8 imsi[15]; uint8 imei[15]; uint8 imeisv[16]; + uint32 tmsi; }LIBLTE_MME_MOBILE_ID_STRUCT; // Functions LIBLTE_ERROR_ENUM liblte_mme_pack_mobile_id_ie(LIBLTE_MME_MOBILE_ID_STRUCT *mobile_id, diff --git a/lib/src/asn1/liblte_mme.cc b/lib/src/asn1/liblte_mme.cc index ea7729519..da79fb791 100644 --- a/lib/src/asn1/liblte_mme.cc +++ b/lib/src/asn1/liblte_mme.cc @@ -297,6 +297,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_mobile_id_ie(LIBLTE_MME_MOBILE_ID_STRUCT *mob { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8 *id; + uint32 id32; uint32 i; uint8 length; bool odd = false; @@ -317,6 +318,11 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_mobile_id_ie(LIBLTE_MME_MOBILE_ID_STRUCT *mob id = mobile_id->imeisv; length = 9; odd = false; + }else if(LIBLTE_MME_MOBILE_ID_TYPE_TMSI == mobile_id->type_of_id){ + id32 = mobile_id->tmsi; + length = 4; + odd = false; + } }else{ // FIXME: Not handling these IDs return(err); @@ -325,30 +331,48 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_mobile_id_ie(LIBLTE_MME_MOBILE_ID_STRUCT *mob // Length **ie_ptr = length; *ie_ptr += 1; - - // | Identity digit 1 | odd/even | Id type | - if(odd) + if(LIBLTE_MME_MOBILE_ID_TYPE_TMSI != mobile_id->type_of_id) { - **ie_ptr = (id[0] << 4) | (1 << 3) | mobile_id->type_of_id; - }else{ - **ie_ptr = (id[0] << 4) | (0 << 3) | mobile_id->type_of_id; - } - *ie_ptr += 1; + // | Identity digit 1 | odd/even | Id type | + if(odd) + { + **ie_ptr = (id[0] << 4) | (1 << 3) | mobile_id->type_of_id; + }else{ + **ie_ptr = (id[0] << 4) | (0 << 3) | mobile_id->type_of_id; + } + *ie_ptr += 1; - // | Identity digit p+1 | Identity digit p | - for(i=0; i<7; i++) - { - (*ie_ptr)[i] = (id[i*2+2] << 4) | id[i*2+1]; - } - *ie_ptr += 7; - if(!odd) - { - **ie_ptr = 0xF0 | id[15]; - *ie_ptr += 1; + + // | Identity digit p+1 | Identity digit p | + for(i=0; i<7; i++) + { + (*ie_ptr)[i] = (id[i*2+2] << 4) | id[i*2+1]; + } + *ie_ptr += 7; + if(!odd) + { + **ie_ptr = 0xF0 | id[15]; + *ie_ptr += 1; + } + + err = LIBLTE_SUCCESS; } + else{ - err = LIBLTE_SUCCESS; - } + **ie_ptr = (0xFF << 4) | (0 << 3) | mobile_id->type_of_id; + *ie_ptr += 1; + //4-Byte based ids + **ie_ptr = (id32 >> 24) & 0xFF; + *ie_ptr += 1; + **ie_ptr = (id32 >> 16) & 0xFF; + *ie_ptr += 1; + **ie_ptr = (id32 >> 8) & 0xFF; + *ie_ptr += 1; + **ie_ptr = id32 & 0xFF; + *ie_ptr += 1; + + err = LIBLTE_SUCCESS; + } return(err); } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index b5c2b8531..736eb4d3d 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -1542,8 +1542,9 @@ s1ap_nas_transport::pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *u } //Attach accept - attach_accept.eps_attach_result = LIBLTE_MME_EPS_ATTACH_RESULT_EPS_ONLY; - //attach_accept.eps_attach_result = LIBLTE_MME_EPS_ATTACH_RESULT_COMBINED_EPS_IMSI_ATTACH; + //attach_accept.eps_attach_result = LIBLTE_MME_EPS_ATTACH_RESULT_EPS_ONLY; + attach_accept.eps_attach_result = LIBLTE_MME_EPS_ATTACH_RESULT_COMBINED_EPS_IMSI_ATTACH; + //Mandatory //FIXME: Set t3412 from config attach_accept.t3412.unit = LIBLTE_MME_GPRS_TIMER_UNIT_1_MINUTE; // GPRS 1 minute unit @@ -1570,13 +1571,22 @@ s1ap_nas_transport::pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *u attach_accept.guti.guti.m_tmsi); //Set EMM cause to no CS available - //attach_accept.emm_cause_present=false; - attach_accept.emm_cause_present=true; - attach_accept.emm_cause=18; + attach_accept.emm_cause_present=false; + //attach_accept.emm_cause_present=true; + //attach_accept.emm_cause=18; + + //Set up LAI for combined EPS/IMSI attach + //attach_accept.lai_present=false; + attach_accept.lai_present=true; + attach_accept.lai.mcc = mcc; + attach_accept.lai.mnc = mnc; + attach_accept.lai.lac = 001; + + attach_accept.ms_id_present=true; + attach_accept.ms_id.type_of_id = LIBLTE_MME_MOBILE_ID_TYPE_TMSI; + attach_accept.ms_id.tmsi = attach_accept.guti.guti.m_tmsi; //Make sure all unused options are set to false - attach_accept.lai_present=false; - attach_accept.ms_id_present=false; attach_accept.t3402_present=false; attach_accept.t3423_present=false; attach_accept.equivalent_plmns_present=false; From bf80a0a21ba363eb207e27f0b25ad899d9e1b758 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 26 Feb 2018 16:42:52 +0100 Subject: [PATCH 136/342] Udated enb.config.example for TM1-4 --- srsenb/enb.conf.example | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 1fafbdc00..9b62d80ca 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -13,6 +13,8 @@ # mme_addr: IP address of MME for S1 connnection # gtp_bind_addr: Local IP address to bind for GTP connection # n_prb: Number of Physical Resource Blocks (6,15,25,50,75,100) +# tm: Transmission mode 1-4 (TM1 default) +# nof_ports: Number of Tx ports (1 port default, set to 2 for TM2/3/4) # ##################################################################### [enb] @@ -25,6 +27,9 @@ mnc = 01 mme_addr = 127.0.1.100 gtp_bind_addr = 127.0.0.1 n_prb = 50 +#tm = 4 +#nof_ports = 2 + ##################################################################### # eNB configuration files From d301d7599f40fcb0bf6fa0205a43c8b2aaf9a4cc Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 26 Feb 2018 16:03:11 +0000 Subject: [PATCH 137/342] Quick and dirty hack to not send activate default eps bearer when a service request is received. --- srsepc/hdr/mme/mme_gtpc.h | 4 ++-- srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h | 2 +- srsepc/hdr/spgw/spgw.h | 2 +- srsepc/src/mme/mme_gtpc.cc | 8 ++++---- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 15 +++++++++++---- srsepc/src/mme/s1ap_nas_transport.cc | 16 +++++++++------- srsepc/src/spgw/spgw.cc | 4 ++-- 7 files changed, 30 insertions(+), 21 deletions(-) diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index 402a52a99..8909e89e2 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -48,8 +48,8 @@ public: bool init(srslte::log_filter *mme_gtpc_log); uint32_t get_new_ctrl_teid(); - void send_create_session_request(uint64_t imsi, uint32_t mme_s1ap_id); - void handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu); + void send_create_session_request(uint64_t imsi, uint32_t mme_s1ap_id, bool pack_attach); + void handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pack_attach); void send_modify_bearer_request(erab_ctx_t *bearer_ctx); void handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu); void send_delete_session_request(ue_ecm_ctx_t *ue_ecm_ctx); diff --git a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h index 44458aea6..1886b9d50 100644 --- a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h @@ -48,7 +48,7 @@ public: void init(void); //bool send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte::gtpc_create_session_response *cs_resp, struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid); - bool send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, ue_ecm_ctx_t *ecm_ctx, erab_ctx_t *erab_ctx); + bool send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, ue_ecm_ctx_t *ecm_ctx, erab_ctx_t *erab_ctx, bool pack_attach); bool handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *in_ctxt_resp); bool handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ue_rel, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); bool send_ue_context_release_command(ue_ecm_ctx_t *ecm_ctx, srslte::byte_buffer_t *reply_buffer); diff --git a/srsepc/hdr/spgw/spgw.h b/srsepc/hdr/spgw/spgw.h index f39674ba7..3837dcf08 100644 --- a/srsepc/hdr/spgw/spgw.h +++ b/srsepc/hdr/spgw/spgw.h @@ -73,7 +73,7 @@ public: void stop(); void run_thread(); - void handle_create_session_request(struct srslte::gtpc_create_session_request *cs_req, struct srslte::gtpc_pdu *cs_resp_pdu); + void handle_create_session_request(struct srslte::gtpc_create_session_request *cs_req, struct srslte::gtpc_pdu *cs_resp_pdu,bool pack_attach); void handle_modify_bearer_request(struct srslte::gtpc_pdu *mb_req_pdu, struct srslte::gtpc_pdu *mb_resp_pdu); void handle_delete_session_request(struct srslte::gtpc_pdu *del_req_pdu, struct srslte::gtpc_pdu *del_resp_pdu); diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index e6f4511df..dd8c7c617 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -88,7 +88,7 @@ mme_gtpc::get_new_ctrl_teid() return m_next_ctrl_teid++; //FIXME Use a Id pool? } void -mme_gtpc::send_create_session_request(uint64_t imsi, uint32_t mme_ue_s1ap_id) +mme_gtpc::send_create_session_request(uint64_t imsi, uint32_t mme_ue_s1ap_id, bool pack_attach) { m_mme_gtpc_log->info("Sending Create Session Request.\n"); m_mme_gtpc_log->console("Sending Create Session Request.\n"); @@ -125,12 +125,12 @@ mme_gtpc::send_create_session_request(uint64_t imsi, uint32_t mme_ue_s1ap_id) //Save RX Control TEID m_teid_to_mme_s1ap_id.insert(std::pair(cs_req->sender_f_teid.teid, mme_ue_s1ap_id)); - m_spgw->handle_create_session_request(cs_req, &cs_resp_pdu); + m_spgw->handle_create_session_request(cs_req, &cs_resp_pdu, pack_attach); } void -mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu) +mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pack_attach) { struct srslte::gtpc_create_session_response *cs_resp = & cs_resp_pdu->choice.create_session_response; m_mme_gtpc_log->info("Received Create Session Response\n"); @@ -206,7 +206,7 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu) erab_ctx->sgw_ctrl_fteid = sgw_ctrl_fteid; erab_ctx->sgw_s1u_fteid = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid; - m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, erab_ctx); + m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, erab_ctx, pack_attach); } diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index c68301ff0..e3332e2d1 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -79,8 +79,10 @@ s1ap_ctx_mngmt_proc::init(void) bool s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, ue_ecm_ctx_t *ecm_ctx, - erab_ctx_t *erab_ctx) + erab_ctx_t *erab_ctx, + bool pack_attach) { + int s1mme = m_s1ap->get_s1_mme(); //Prepare reply PDU @@ -159,16 +161,21 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, m_s1ap_log->info_hex(emm_ctx->security_ctxt.k_enb, 32, "Initial Context Setup Request -- Key eNB\n"); srslte::byte_buffer_t *nas_buffer = m_pool->allocate(); - m_s1ap_nas_transport->pack_attach_accept(emm_ctx, ecm_ctx, erab_ctx_req, &erab_ctx->pdn_addr_alloc, nas_buffer); + if(pack_attach) + { + pack_attach = false; + m_s1ap_nas_transport->pack_attach_accept(emm_ctx, ecm_ctx, erab_ctx_req, &erab_ctx->pdn_addr_alloc, nas_buffer); + + } - LIBLTE_ERROR_ENUM err = liblte_s1ap_pack_s1ap_pdu(&pdu, (LIBLTE_BYTE_MSG_STRUCT*)reply_buffer); if(err != LIBLTE_SUCCESS) { m_s1ap_log->error("Could not pack Initial Context Setup Request Message\n"); return false; } - //Send Reply to eNB + + //Send Reply to eNB ssize_t n_sent = sctp_send(s1mme,reply_buffer->msg, reply_buffer->N_bytes, &ecm_ctx->enb_sri, 0); if(n_sent == -1) { diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 736eb4d3d..e84d19b78 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -578,7 +578,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); //Create session request m_s1ap_log->console("GUTI Attach -- NAS Integrity OK."); - m_mme_gtpc->send_create_session_request(ue_emm_ctx->imsi, ue_emm_ctx->mme_ue_s1ap_id); + m_mme_gtpc->send_create_session_request(ue_emm_ctx->imsi, ue_emm_ctx->mme_ue_s1ap_id,true); *reply_flag = false; //No reply needed return true; } @@ -652,7 +652,7 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, m_s1ap_log->info("Service Request -- User has ECM context already\n"); m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); int default_bearer_id = 5; - m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ue_emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[default_bearer_id]); + m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ue_emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[default_bearer_id],false); } else { @@ -685,7 +685,9 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, //Re-generate K_eNB liblte_security_generate_k_enb(ue_emm_ctx->security_ctxt.k_asme, ue_emm_ctx->security_ctxt.ul_nas_count, ue_emm_ctx->security_ctxt.k_enb); m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",ue_emm_ctx->security_ctxt.ul_nas_count); - m_mme_gtpc->send_create_session_request(ue_ecm_ctx.imsi, ue_ecm_ctx.mme_ue_s1ap_id); + + m_mme_gtpc->send_create_session_request(ue_ecm_ctx.imsi, ue_ecm_ctx.mme_ue_s1ap_id,false); + // m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ue_); } } else @@ -798,7 +800,7 @@ s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas { //FIXME The packging of GTP-C messages is not ready. //This means that GTP-U tunnels are created with function calls, as opposed to GTP-C. - m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi, ue_ecm_ctx->mme_ue_s1ap_id); + m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi, ue_ecm_ctx->mme_ue_s1ap_id,true); *reply_flag = false; //No reply needed } return true; @@ -867,7 +869,7 @@ s1ap_nas_transport::handle_esm_information_response(srslte::byte_buffer_t *nas_m //FIXME The packging of GTP-C messages is not ready. //This means that GTP-U tunnels are created with function calls, as opposed to GTP-C. - m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi, ue_ecm_ctx->mme_ue_s1ap_id); + m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi, ue_ecm_ctx->mme_ue_s1ap_id,true); return true; } @@ -1577,12 +1579,12 @@ s1ap_nas_transport::pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *u //Set up LAI for combined EPS/IMSI attach //attach_accept.lai_present=false; - attach_accept.lai_present=true; + attach_accept.lai_present=false; attach_accept.lai.mcc = mcc; attach_accept.lai.mnc = mnc; attach_accept.lai.lac = 001; - attach_accept.ms_id_present=true; + attach_accept.ms_id_present=false; attach_accept.ms_id.type_of_id = LIBLTE_MME_MOBILE_ID_TYPE_TMSI; attach_accept.ms_id.tmsi = attach_accept.guti.guti.m_tmsi; diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index 7bc47f496..6904b3ee3 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -437,7 +437,7 @@ spgw::get_new_ue_ipv4() } void -spgw::handle_create_session_request(struct srslte::gtpc_create_session_request *cs_req, struct srslte::gtpc_pdu *cs_resp_pdu) +spgw::handle_create_session_request(struct srslte::gtpc_create_session_request *cs_req, struct srslte::gtpc_pdu *cs_resp_pdu, bool pack_attach) { srslte::gtpc_header *header = &cs_resp_pdu->header; srslte::gtpc_create_session_response *cs_resp = &cs_resp_pdu->choice.create_session_response; @@ -492,7 +492,7 @@ spgw::handle_create_session_request(struct srslte::gtpc_create_session_request * cs_resp->paa.ipv4_present = true; cs_resp->paa.ipv4 = ue_ip; m_spgw_log->info("Sending Create Session Response\n"); - m_mme_gtpc->handle_create_session_response(cs_resp_pdu); + m_mme_gtpc->handle_create_session_response(cs_resp_pdu, pack_attach ); return; } From ea0585a772f5a787823336ba8249032db4571a27 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 26 Feb 2018 18:50:53 +0000 Subject: [PATCH 138/342] Quick hack to keep the IP in service request. --- srsepc/src/mme/mme_gtpc.cc | 3 +++ srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 7 ++++++- srsepc/src/mme/s1ap_nas_transport.cc | 3 ++- srsepc/src/spgw/spgw.cc | 8 ++++---- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index dd8c7c617..ab383bf52 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -157,6 +157,7 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pac } uint32_t mme_s1ap_id = id_it->second; + m_mme_gtpc_log->info("MME GTPC Ctrl TEID %d, MME UE S1AP Id %d\n", cs_resp_pdu->header.teid, mme_s1ap_id); //Get S-GW Control F-TEID srslte::gtpc_f_teid_ie sgw_ctrl_fteid; sgw_ctrl_fteid.teid = cs_resp_pdu->header.teid; @@ -168,9 +169,11 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pac return; } m_mme_gtpc_log->console("Create Session Response -- SPGW control TEID %d\n", sgw_ctrl_fteid.teid); + m_mme_gtpc_log->info("Create Session Response -- SPGW control TEID %d\n", sgw_ctrl_fteid.teid); in_addr s1u_addr; s1u_addr.s_addr = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.ipv4; m_mme_gtpc_log->console("Create Session Response -- SPGW S1-U Address: %s\n", inet_ntoa(s1u_addr)); + m_mme_gtpc_log->info("Create Session Response -- SPGW S1-U Address: %s\n", inet_ntoa(s1u_addr)); //Check UE Ipv4 address was allocated if(cs_resp->paa_present != true) diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index e3332e2d1..83b5c9594 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -203,7 +203,7 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, bool s1ap_ctx_mngmt_proc::handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *in_ctxt_resp) { - + static bool send_modify = false; uint32_t mme_ue_s1ap_id = in_ctxt_resp->MME_UE_S1AP_ID.MME_UE_S1AP_ID; ue_ecm_ctx_t *ue_ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); if (ue_ecm_ctx == NULL) @@ -244,6 +244,11 @@ s1ap_ctx_mngmt_proc::handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_I m_s1ap_log->console("E-RAB Context -- eNB TEID 0x%x; eNB GTP-U Address %s\n", erab_ctx->enb_fteid.teid, enb_addr_str); } + if(send_modify) + { + m_mme_gtpc->send_modify_bearer_request(&ue_ecm_ctx->erabs_ctx[5]); + } + send_modify = true; return true; } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index e84d19b78..bdea825de 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -687,7 +687,8 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",ue_emm_ctx->security_ctxt.ul_nas_count); m_mme_gtpc->send_create_session_request(ue_ecm_ctx.imsi, ue_ecm_ctx.mme_ue_s1ap_id,false); - // m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ue_); + m_s1ap_log->console("UE ESM Ctr TEID %d\n", ue_ecm_ctx.erabs_ctx[5].sgw_ctrl_fteid.teid); + // m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ue_); } } else diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index 6904b3ee3..df62fa43b 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -338,7 +338,7 @@ spgw::handle_sgi_pdu(srslte::byte_buffer_t *msg) dest_addr.s_addr = dest_ip; //m_spgw_log->console("IP version: %d\n", version); - //m_spgw_log->console("Received packet to IP: %s\n", inet_ntoa(dest_addr)); + m_spgw_log->console("Received packet to IP: %s\n", inet_ntoa(dest_addr)); pthread_mutex_lock(&m_mutex); gtp_fteid_it = m_ip_to_teid.find(dest_ip); @@ -351,7 +351,7 @@ spgw::handle_sgi_pdu(srslte::byte_buffer_t *msg) if(ip_found == false) { - //m_spgw_log->console("IP Packet is not for any UE\n"); + m_spgw_log->console("IP Packet is not for any UE\n"); return; } struct sockaddr_in enb_addr; @@ -449,8 +449,8 @@ spgw::handle_create_session_request(struct srslte::gtpc_create_session_request * //Setup uplink user TEID uint64_t spgw_uplink_user_teid = get_new_user_teid(); //Allocate UE IP - in_addr_t ue_ip = get_new_ue_ipv4(); - + //in_addr_t ue_ip = get_new_ue_ipv4(); + in_addr_t ue_ip = inet_addr("172.16.0.2"); uint8_t default_bearer_id = 5; //Save the UE IP to User TEID map From f7348e8ddf05a4065bae35fd0e5de28731f15197 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 26 Feb 2018 19:37:41 +0000 Subject: [PATCH 139/342] Added print to show unhandled S1AP messages. --- srsepc/src/mme/s1ap.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 3cd47d6b9..c0c8ee630 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -250,7 +250,8 @@ s1ap::handle_initiating_message(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg, stru m_s1ap_ctx_mngmt_proc->handle_ue_context_release_request(&msg->choice.UEContextReleaseRequest, enb_sri, reply_buffer, &reply_flag); break; default: - m_s1ap_log->error("Unhandled intiating message: %s\n", liblte_s1ap_initiatingmessage_choice_text[msg->choice_type]); + m_s1ap_log->error("Unhandled S1AP intiating message: %s\n", liblte_s1ap_initiatingmessage_choice_text[msg->choice_type]); + m_s1ap_log->console("Unhandled S1APintiating message: %s\n", liblte_s1ap_initiatingmessage_choice_text[msg->choice_type]); } //Send Reply to eNB if(reply_flag == true) From ecb846717c8304059b6cfa8d4e63f19bfb044443 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 27 Feb 2018 13:33:43 +0000 Subject: [PATCH 140/342] Starting to handle UE capability info indication --- srsepc/hdr/mme/s1ap.h | 6 ++- srsepc/hdr/mme/s1ap_ue_cap_info.h | 60 +++++++++++++++++++++++ srsepc/src/mme/s1ap.cc | 4 ++ srsepc/src/mme/s1ap_ue_cap_info.cc | 77 ++++++++++++++++++++++++++++++ 4 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 srsepc/hdr/mme/s1ap_ue_cap_info.h create mode 100644 srsepc/src/mme/s1ap_ue_cap_info.cc diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 774831840..3f9f035e0 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -44,6 +44,7 @@ #include "mme/s1ap_mngmt_proc.h" #include "mme/s1ap_nas_transport.h" #include "mme/s1ap_ctx_mngmt_proc.h" +#include "mme/s1ap_ue_cap_info.h" #include "mme/mme_gtpc.h" #include "hss/hss.h" @@ -100,8 +101,9 @@ public: srslte::log_filter *m_s1ap_log; s1ap_mngmt_proc* m_s1ap_mngmt_proc; - s1ap_nas_transport* m_s1ap_nas_transport; - s1ap_ctx_mngmt_proc* m_s1ap_ctx_mngmt_proc; + s1ap_nas_transport* m_s1ap_nas_transport; + s1ap_ctx_mngmt_proc* m_s1ap_ctx_mngmt_proc; + s1ap_ue_cap_info* m_s1ap_ue_cap_info; std::map m_tmsi_to_imsi; diff --git a/srsepc/hdr/mme/s1ap_ue_cap_info.h b/srsepc/hdr/mme/s1ap_ue_cap_info.h new file mode 100644 index 000000000..59bb37ea3 --- /dev/null +++ b/srsepc/hdr/mme/s1ap_ue_cap_info.h @@ -0,0 +1,60 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2017 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of srsLTE. + * + * srsLTE 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. + * + * srsLTE 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/. + * + */ +#ifndef S1AP_UE_CAP_INFO_H +#define S1AP_UE_CAP_INFO_H + +#include "srslte/asn1/liblte_s1ap.h" +#include "srslte/common/common.h" +#include "mme/s1ap_common.h" +#include "srslte/common/log_filter.h" + +namespace srsepc{ + +class s1ap; + +class s1ap_ue_cap_info +{ +public: + + static s1ap_ue_cap_info *m_instance; + + static s1ap_ue_cap_info* get_instance(void); + static void cleanup(void); + void init(void); + + bool handle_ue_capability_info_indication(LIBLTE_S1AP_MESSAGE_UECAPABILITYINFOINDICATION_STRUCT *msg, sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); + +private: + s1ap_ue_cap_info(); + virtual ~s1ap_ue_cap_info(); + + s1ap* m_s1ap; + srslte::log_filter *m_s1ap_log; +}; + +} //namespace srsepc + +#endif //S1AP_MNGMT_PROC diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index c0c8ee630..d0b765fd4 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -249,6 +249,10 @@ s1ap::handle_initiating_message(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg, stru m_s1ap_log->info("Received UE Context Release Request Message.\n"); m_s1ap_ctx_mngmt_proc->handle_ue_context_release_request(&msg->choice.UEContextReleaseRequest, enb_sri, reply_buffer, &reply_flag); break; + case LIBLTE_S1AP_PROC_ID_UECAPABILITYINFOINDICATION: + m_s1ap_log->info("Received UE Context Release Request Message.\n"); + m_s1ap_ue_cap_info->handle_ue_capability_info_indication(&msg->choice.UECapabilityInfoIndication, enb_sri, reply_buffer, &reply_flag); + break; default: m_s1ap_log->error("Unhandled S1AP intiating message: %s\n", liblte_s1ap_initiatingmessage_choice_text[msg->choice_type]); m_s1ap_log->console("Unhandled S1APintiating message: %s\n", liblte_s1ap_initiatingmessage_choice_text[msg->choice_type]); diff --git a/srsepc/src/mme/s1ap_ue_cap_info.cc b/srsepc/src/mme/s1ap_ue_cap_info.cc new file mode 100644 index 000000000..357bb507c --- /dev/null +++ b/srsepc/src/mme/s1ap_ue_cap_info.cc @@ -0,0 +1,77 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2017 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of srsLTE. + * + * srsLTE 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. + * + * srsLTE 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 "mme/s1ap.h" +#include "mme/s1ap_ue_cap_info.h" + +namespace srsepc{ + +s1ap_ue_cap_info* s1ap_ue_cap_info::m_instance = NULL; +boost::mutex s1ap_ue_cap_info_instance_mutex; + + +s1ap_ue_cap_info::s1ap_ue_cap_info() +{ +} + +s1ap_ue_cap_info::~s1ap_ue_cap_info() +{ +} + +s1ap_ue_cap_info* +s1ap_ue_cap_info::get_instance(void) +{ + boost::mutex::scoped_lock lock(s1ap_ue_cap_info_instance_mutex); + if(NULL == m_instance) { + m_instance = new s1ap_ue_cap_info(); + } + return(m_instance); +} + +void +s1ap_ue_cap_info::cleanup(void) +{ + boost::mutex::scoped_lock lock(s1ap_ue_cap_info_instance_mutex); + if(NULL != m_instance) { + delete m_instance; + m_instance = NULL; + } +} + +void +s1ap_ue_cap_info::init(void) +{ + m_s1ap = s1ap::get_instance(); + m_s1ap_log = m_s1ap->m_s1ap_log; +} + +bool +s1ap_ue_cap_info::handle_ue_capability_info_indication(LIBLTE_S1AP_MESSAGE_UECAPABILITYINFOINDICATION_STRUCT *msg, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag) +{ + m_s1ap_log->info("UE Capability Info Indication\n"); + return true; +} + +} //namespace srsepc From fc280e082fb9437ec63a42c9a2965b34932fd745 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 27 Feb 2018 14:45:11 +0000 Subject: [PATCH 141/342] Continuing to add UE capabilities info indication. --- srsepc/src/mme/s1ap.cc | 12 ++++++++---- srsepc/src/mme/s1ap_nas_transport.cc | 4 ++-- srsepc/src/mme/s1ap_ue_cap_info.cc | 1 + 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index d0b765fd4..921e5ff84 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -82,12 +82,15 @@ s1ap::init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log, hss_interface_s1 m_hss = hss_; //Init message handlers - m_s1ap_mngmt_proc = s1ap_mngmt_proc::get_instance(); //Managment procedures + 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 = s1ap_nas_transport::get_instance(); //NAS Transport procedures 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(); + m_s1ap_ue_cap_info = s1ap_ue_cap_info::get_instance(); //UE Capability Information + m_s1ap_ue_cap_info->init(); + //Get pointer to GTP-C class m_mme_gtpc = mme_gtpc::get_instance(); @@ -126,6 +129,7 @@ s1ap::stop() s1ap_mngmt_proc::cleanup(); s1ap_nas_transport::cleanup(); s1ap_ctx_mngmt_proc::cleanup(); + s1ap_ue_cap_info::cleanup(); return; } @@ -226,7 +230,7 @@ s1ap::handle_s1ap_rx_pdu(srslte::byte_buffer_t *pdu, struct sctp_sndrcvinfo *enb } -bool +bool s1ap::handle_initiating_message(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg, struct sctp_sndrcvinfo *enb_sri) { bool reply_flag = false; @@ -249,7 +253,7 @@ s1ap::handle_initiating_message(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg, stru m_s1ap_log->info("Received UE Context Release Request Message.\n"); m_s1ap_ctx_mngmt_proc->handle_ue_context_release_request(&msg->choice.UEContextReleaseRequest, enb_sri, reply_buffer, &reply_flag); break; - case LIBLTE_S1AP_PROC_ID_UECAPABILITYINFOINDICATION: + case LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECAPABILITYINFOINDICATION: m_s1ap_log->info("Received UE Context Release Request Message.\n"); m_s1ap_ue_cap_info->handle_ue_capability_info_indication(&msg->choice.UECapabilityInfoIndication, enb_sri, reply_buffer, &reply_flag); break; diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index bdea825de..f0767292c 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -1580,12 +1580,12 @@ s1ap_nas_transport::pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *u //Set up LAI for combined EPS/IMSI attach //attach_accept.lai_present=false; - attach_accept.lai_present=false; + attach_accept.lai_present=true; attach_accept.lai.mcc = mcc; attach_accept.lai.mnc = mnc; attach_accept.lai.lac = 001; - attach_accept.ms_id_present=false; + attach_accept.ms_id_present=true; attach_accept.ms_id.type_of_id = LIBLTE_MME_MOBILE_ID_TYPE_TMSI; attach_accept.ms_id.tmsi = attach_accept.guti.guti.m_tmsi; diff --git a/srsepc/src/mme/s1ap_ue_cap_info.cc b/srsepc/src/mme/s1ap_ue_cap_info.cc index 357bb507c..f06fde165 100644 --- a/srsepc/src/mme/s1ap_ue_cap_info.cc +++ b/srsepc/src/mme/s1ap_ue_cap_info.cc @@ -71,6 +71,7 @@ bool s1ap_ue_cap_info::handle_ue_capability_info_indication(LIBLTE_S1AP_MESSAGE_UECAPABILITYINFOINDICATION_STRUCT *msg, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag) { m_s1ap_log->info("UE Capability Info Indication\n"); + m_s1ap_log->console("UE Capability Info Indication\n"); return true; } From 6fc9c96c58b7856c3a23ec87a3ceccd0a0e3129f Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 28 Feb 2018 12:02:17 +0100 Subject: [PATCH 142/342] Added CSI softbits weightening for Single antenna transmission --- lib/include/srslte/phy/mimo/precoding.h | 3 + lib/include/srslte/phy/phch/pdsch.h | 6 ++ lib/include/srslte/phy/utils/simd.h | 12 +++- .../phy/ch_estimation/test/chest_test_dl.c | 4 +- lib/src/phy/mimo/precoding.c | 58 +++++++++++++++++-- lib/src/phy/mimo/test/precoder_test.c | 2 +- lib/src/phy/phch/pbch.c | 2 +- lib/src/phy/phch/pcfich.c | 2 +- lib/src/phy/phch/pdcch.c | 2 +- lib/src/phy/phch/pdsch.c | 52 ++++++++++++++++- lib/src/phy/phch/phich.c | 2 +- lib/src/phy/phch/pmch.c | 2 +- lib/src/phy/phch/pucch.c | 2 +- lib/src/phy/phch/pusch.c | 2 +- 14 files changed, 135 insertions(+), 16 deletions(-) diff --git a/lib/include/srslte/phy/mimo/precoding.h b/lib/include/srslte/phy/mimo/precoding.h index f8463d1cb..27395085c 100644 --- a/lib/include/srslte/phy/mimo/precoding.h +++ b/lib/include/srslte/phy/mimo/precoding.h @@ -79,6 +79,7 @@ SRSLTE_API int srslte_precoding_type(cf_t *x[SRSLTE_MAX_LAYERS], SRSLTE_API int srslte_predecoding_single(cf_t *y, cf_t *h, cf_t *x, + float *csi, int nof_symbols, float scaling, float noise_estimate); @@ -86,6 +87,7 @@ SRSLTE_API int srslte_predecoding_single(cf_t *y, SRSLTE_API int srslte_predecoding_single_multi(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS], cf_t *x, + float *csi, int nof_rxant, int nof_symbols, float scaling, @@ -111,6 +113,7 @@ SRSLTE_API void srslte_predecoding_set_mimo_decoder (srslte_mimo_decoder_t _mimo SRSLTE_API int srslte_predecoding_type(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], + float *csi, int nof_rxant, int nof_ports, int nof_layers, diff --git a/lib/include/srslte/phy/phch/pdsch.h b/lib/include/srslte/phy/phch/pdsch.h index dab900d77..1889078e6 100644 --- a/lib/include/srslte/phy/phch/pdsch.h +++ b/lib/include/srslte/phy/phch/pdsch.h @@ -76,6 +76,9 @@ typedef struct SRSLTE_API { cf_t *d[SRSLTE_MAX_CODEWORDS]; /* Modulated/Demodulated codewords */ void *e[SRSLTE_MAX_CODEWORDS]; + bool csi_enabled; + float *csi[SRSLTE_MAX_CODEWORDS]; /* Channel Strengh Indicator */ + /* tx & rx objects */ srslte_modem_table_t mod[4]; @@ -107,6 +110,9 @@ SRSLTE_API int srslte_pdsch_set_rnti(srslte_pdsch_t *q, SRSLTE_API void srslte_pdsch_set_power_allocation(srslte_pdsch_t *q, float rho_a); +SRSLTE_API int srslte_pdsch_enable_csi(srslte_pdsch_t *q, + bool enable); + SRSLTE_API void srslte_pdsch_free_rnti(srslte_pdsch_t *q, uint16_t rnti); diff --git a/lib/include/srslte/phy/utils/simd.h b/lib/include/srslte/phy/utils/simd.h index e22a9ef09..3b5a00a8a 100644 --- a/lib/include/srslte/phy/utils/simd.h +++ b/lib/include/srslte/phy/utils/simd.h @@ -530,7 +530,7 @@ static inline simd_cf_t srslte_simd_cfi_loadu(const cf_t *ptr) { 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F), in2); #else /* LV_HAVE_AVX512 */ - #ifdef LV_HAVE_AVX2 +#ifdef LV_HAVE_AVX2 __m256 in1 = _mm256_permute_ps(_mm256_loadu_ps((float*)(ptr)), 0b11011000); __m256 in2 = _mm256_permute_ps(_mm256_loadu_ps((float*)(ptr + 4)), 0b11011000); ret.re = _mm256_unpacklo_ps(in1, in2); @@ -705,6 +705,16 @@ static inline void srslte_simd_cf_storeu(float *re, float *im, simd_cf_t simdreg #endif /* LV_HAVE_AVX512 */ } +static inline simd_f_t srslte_simd_cf_re(simd_cf_t in) { + simd_f_t out = in.re; +#ifdef LV_HAVE_AVX2 + /* Permute for AVX registers (mis SSE registers) */ + const __m256i idx = _mm256_setr_epi32(0, 2, 4, 6, 1, 3, 5, 7); + out = _mm256_permutevar8x32_ps(out, idx); +#endif /* LV_HAVE_AVX2 */ + return out; +} + static inline simd_cf_t srslte_simd_cf_set1 (cf_t x) { simd_cf_t ret; #ifdef LV_HAVE_AVX512 diff --git a/lib/src/phy/ch_estimation/test/chest_test_dl.c b/lib/src/phy/ch_estimation/test/chest_test_dl.c index 62f7e1c86..222263c7e 100644 --- a/lib/src/phy/ch_estimation/test/chest_test_dl.c +++ b/lib/src/phy/ch_estimation/test/chest_test_dl.c @@ -173,7 +173,7 @@ int main(int argc, char **argv) { gettimeofday(&t[1], NULL); for (int j=0;j<100;j++) { - srslte_predecoding_single(input, ce, output, num_re, 1.0f, 0); + srslte_predecoding_single(input, ce, output, NULL, num_re, 1.0f, 0); } gettimeofday(&t[2], NULL); get_time_interval(t); @@ -188,7 +188,7 @@ int main(int argc, char **argv) { gettimeofday(&t[1], NULL); for (int j=0;j<100;j++) { - srslte_predecoding_single(input, ce, output, num_re, 1.0f, srslte_chest_dl_get_noise_estimate(&est)); + srslte_predecoding_single(input, ce, output, NULL, num_re, 1.0f, srslte_chest_dl_get_noise_estimate(&est)); } gettimeofday(&t[2], NULL); get_time_interval(t); diff --git a/lib/src/phy/mimo/precoding.c b/lib/src/phy/mimo/precoding.c index 6d50e3ed2..f8faeda75 100644 --- a/lib/src/phy/mimo/precoding.c +++ b/lib/src/phy/mimo/precoding.c @@ -34,6 +34,7 @@ #include "srslte/phy/utils/vector.h" #include "srslte/phy/utils/debug.h" #include "srslte/phy/utils/mat.h" +#include "srslte/phy/utils/simd.h" #ifdef LV_HAVE_SSE #include @@ -252,8 +253,49 @@ int srslte_predecoding_single_gen(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_ return nof_symbols; } +int srslte_predecoding_single_csi(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS], cf_t *x, float *csi, int nof_rxant, int nof_symbols, float scaling, float noise_estimate) { + int i = 0; + +#if SRSLTE_SIMD_CF_SIZE + const simd_f_t _noise = srslte_simd_f_set1(noise_estimate); + const simd_f_t _scaling = srslte_simd_f_set1(1.0f / scaling); + + for (; i < nof_symbols - SRSLTE_SIMD_CF_SIZE + 1; i += SRSLTE_SIMD_CF_SIZE) { + simd_cf_t _r = srslte_simd_cf_zero(); + simd_f_t _hh = srslte_simd_f_zero(); + + for (int p = 0; p < nof_rxant; p++) { + simd_cf_t _y = srslte_simd_cfi_load(&y[p][i]); + simd_cf_t _h = srslte_simd_cfi_load(&h[p][i]); + + _r = srslte_simd_cf_add(_r, srslte_simd_cf_conjprod(_y, _h)); + _hh = srslte_simd_f_add(_hh, srslte_simd_cf_re(srslte_simd_cf_conjprod(_h, _h))); + } + + simd_f_t _csi = srslte_simd_f_add(_hh, _noise); + simd_cf_t _x = srslte_simd_cf_mul(srslte_simd_cf_mul(_r, _scaling), srslte_simd_f_rcp(_csi)); + + srslte_simd_f_store(&csi[i], _csi); + srslte_simd_cfi_store(&x[i], _x); + } +#endif + + for (; i < nof_symbols; i++) { + cf_t r = 0; + float hh = 0; + float _scaling = 1.0f / scaling; + for (int p = 0; p < nof_rxant; p++) { + r += y[p][i] * conj(h[p][i]); + hh += (__real__ h[p][i] * __real__ h[p][i]) + (__imag__ h[p][i] * __imag__ h[p][i]); + } + csi[i] = hh + noise_estimate; + x[i] = r * _scaling / csi[i]; + } + return nof_symbols; +} + /* ZF/MMSE SISO equalizer x=y(h'h+no)^(-1)h' (ZF if n0=0.0)*/ -int srslte_predecoding_single(cf_t *y_, cf_t *h_, cf_t *x, int nof_symbols, float scaling, float noise_estimate) { +int srslte_predecoding_single(cf_t *y_, cf_t *h_, cf_t *x, float *csi, int nof_symbols, float scaling, float noise_estimate) { cf_t *y[SRSLTE_MAX_PORTS]; cf_t *h[SRSLTE_MAX_PORTS]; @@ -261,6 +303,10 @@ int srslte_predecoding_single(cf_t *y_, cf_t *h_, cf_t *x, int nof_symbols, floa h[0] = h_; int nof_rxant = 1; + if (csi) { + return srslte_predecoding_single_csi(y, h, x, csi, nof_rxant, nof_symbols, scaling, noise_estimate); + } + #ifdef LV_HAVE_AVX if (nof_symbols > 32 && nof_rxant <= 2) { return srslte_predecoding_single_avx(y, h, x, nof_rxant, nof_symbols, scaling, noise_estimate); @@ -281,8 +327,12 @@ int srslte_predecoding_single(cf_t *y_, cf_t *h_, cf_t *x, int nof_symbols, floa } /* ZF/MMSE SISO equalizer x=y(h'h+no)^(-1)h' (ZF if n0=0.0)*/ -int srslte_predecoding_single_multi(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS], cf_t *x, +int srslte_predecoding_single_multi(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS], cf_t *x, float *csi, int nof_rxant, int nof_symbols, float scaling, float noise_estimate) { + if (csi) { + return srslte_predecoding_single_csi(y, h, x, csi, nof_rxant, nof_symbols, scaling, noise_estimate); + } + #ifdef LV_HAVE_AVX if (nof_symbols > 32) { return srslte_predecoding_single_avx(y, h, x, nof_rxant, nof_symbols, scaling, noise_estimate); @@ -1418,7 +1468,7 @@ void srslte_predecoding_set_mimo_decoder (srslte_mimo_decoder_t _mimo_decoder) { /* 36.211 v10.3.0 Section 6.3.4 */ int srslte_predecoding_type(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], - cf_t *x[SRSLTE_MAX_LAYERS], int nof_rxant, int nof_ports, int nof_layers, + cf_t *x[SRSLTE_MAX_LAYERS], float *csi, int nof_rxant, int nof_ports, int nof_layers, int codebook_idx, int nof_symbols, srslte_mimo_type_t type, float scaling, float noise_estimate) { @@ -1451,7 +1501,7 @@ int srslte_predecoding_type(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS] return -1; case SRSLTE_MIMO_TYPE_SINGLE_ANTENNA: if (nof_ports == 1 && nof_layers == 1) { - return srslte_predecoding_single_multi(y, h[0], x[0], nof_rxant, nof_symbols, scaling, noise_estimate); + return srslte_predecoding_single_multi(y, h[0], x[0], csi, nof_rxant, nof_symbols, scaling, noise_estimate); } else { fprintf(stderr, "Number of ports and layers must be 1 for transmission on single antenna ports (%d, %d)\n", nof_ports, nof_layers); diff --git a/lib/src/phy/mimo/test/precoder_test.c b/lib/src/phy/mimo/test/precoder_test.c index 1054545c3..a6925f318 100644 --- a/lib/src/phy/mimo/test/precoder_test.c +++ b/lib/src/phy/mimo/test/precoder_test.c @@ -291,7 +291,7 @@ int main(int argc, char **argv) { /* predecoding / equalization */ struct timeval t[3]; gettimeofday(&t[1], NULL); - srslte_predecoding_type(r, h, xr, nof_rx_ports, nof_tx_ports, nof_layers, + srslte_predecoding_type(r, h, xr, NULL, nof_rx_ports, nof_tx_ports, nof_layers, codebook_idx, nof_re, type, scaling, powf(10, -snr_db / 10)); gettimeofday(&t[2], NULL); get_time_interval(t); diff --git a/lib/src/phy/phch/pbch.c b/lib/src/phy/phch/pbch.c index c72b12c60..e7c0c33af 100644 --- a/lib/src/phy/phch/pbch.c +++ b/lib/src/phy/phch/pbch.c @@ -497,7 +497,7 @@ int srslte_pbch_decode(srslte_pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[SRS /* in control channels, only diversity is supported */ if (nant == 1) { /* no need for layer demapping */ - srslte_predecoding_single(q->symbols[0], q->ce[0], q->d, q->nof_symbols, 1.0f, noise_estimate); + srslte_predecoding_single(q->symbols[0], q->ce[0], q->d, NULL, q->nof_symbols, 1.0f, noise_estimate); } else { srslte_predecoding_diversity(q->symbols[0], q->ce, x, nant, q->nof_symbols, 1.0f); diff --git a/lib/src/phy/phch/pcfich.c b/lib/src/phy/phch/pcfich.c index 7269000a8..6b00e768a 100644 --- a/lib/src/phy/phch/pcfich.c +++ b/lib/src/phy/phch/pcfich.c @@ -219,7 +219,7 @@ int srslte_pcfich_decode_multi(srslte_pcfich_t *q, cf_t *sf_symbols[SRSLTE_MAX_P /* in control channels, only diversity is supported */ if (q->cell.nof_ports == 1) { /* no need for layer demapping */ - srslte_predecoding_single_multi(q_symbols, q_ce[0], q->d, q->nof_rx_antennas, q->nof_symbols, 1.0f, noise_estimate); + srslte_predecoding_single_multi(q_symbols, q_ce[0], q->d, NULL, q->nof_rx_antennas, q->nof_symbols, 1.0f, noise_estimate); } else { srslte_predecoding_diversity_multi(q_symbols, q_ce, x, q->nof_rx_antennas, q->cell.nof_ports, q->nof_symbols, 1.0f); srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports, q->nof_symbols / q->cell.nof_ports); diff --git a/lib/src/phy/phch/pdcch.c b/lib/src/phy/phch/pdcch.c index 206ef1be6..83f681f8f 100644 --- a/lib/src/phy/phch/pdcch.c +++ b/lib/src/phy/phch/pdcch.c @@ -490,7 +490,7 @@ int srslte_pdcch_extract_llr_multi(srslte_pdcch_t *q, cf_t *sf_symbols[SRSLTE_MA /* in control channels, only diversity is supported */ if (q->cell.nof_ports == 1) { /* no need for layer demapping */ - srslte_predecoding_single_multi(q->symbols, q->ce[0], q->d, q->nof_rx_antennas, nof_symbols, 1.0f, noise_estimate/2); + srslte_predecoding_single_multi(q->symbols, q->ce[0], q->d, NULL, q->nof_rx_antennas, nof_symbols, 1.0f, noise_estimate/2); } else { srslte_predecoding_diversity_multi(q->symbols, q->ce, x, q->nof_rx_antennas, q->cell.nof_ports, nof_symbols, 1.0f); srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports, nof_symbols / q->cell.nof_ports); diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index 1cf4af4e2..4cfa5c75c 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -294,6 +294,10 @@ void srslte_pdsch_free(srslte_pdsch_t *q) { if (q->d[i]) { free(q->d[i]); } + + if (q->csi[i]) { + free(q->csi[i]); + } } /* Free sch objects */ @@ -394,6 +398,22 @@ void srslte_pdsch_set_power_allocation(srslte_pdsch_t *q, float rho_a) { } } +int srslte_pdsch_enable_csi(srslte_pdsch_t *q, bool enable) { + if (enable) { + for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { + if (!q->csi[i]) { + q->csi[i] = srslte_vec_malloc(sizeof(float) * q->max_re); + if (!q->csi[i]) { + return SRSLTE_ERROR; + } + } + } + } + q->csi_enabled = enable; + + return SRSLTE_SUCCESS; +} + void srslte_pdsch_free_rnti(srslte_pdsch_t* q, uint16_t rnti) { uint32_t rnti_idx = q->is_ue?0:rnti; @@ -617,6 +637,36 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *c /* Bit scrambling */ srslte_scrambling_s_offset(seq, q->e[codeword_idx], 0, nbits->nof_bits); + uint32_t qm = nbits->nof_bits/nbits->nof_re; + switch(cfg->grant.mcs[tb_idx].mod) { + + case SRSLTE_MOD_BPSK: + qm = 1; + break; + case SRSLTE_MOD_QPSK: + qm = 2; + break; + case SRSLTE_MOD_16QAM: + qm = 4; + break; + case SRSLTE_MOD_64QAM: + qm = 6; + break; + default: + ERROR("No modulation"); + } + + int16_t *e = q->e[codeword_idx]; + + if (q->csi_enabled) { + for (int i = 0; i < nbits->nof_bits / qm; i++) { + float csi = q->csi[codeword_idx][i]; + for (int k = 0; k < qm; k++) { + e[qm * i + k] = (int16_t) ((float) e[qm * i + k] * csi); + } + } + } + /* Return */ ret = srslte_dlsch_decode2(&q->dl_sch, cfg, softbuffer, q->e[codeword_idx], data, tb_idx); @@ -702,7 +752,7 @@ int srslte_pdsch_decode(srslte_pdsch_t *q, } // Pre-decoder - if (srslte_predecoding_type(q->symbols, q->ce, x, q->nof_rx_antennas, q->cell.nof_ports, cfg->nof_layers, + if (srslte_predecoding_type(q->symbols, q->ce, x, q->csi[0], q->nof_rx_antennas, q->cell.nof_ports, cfg->nof_layers, cfg->codebook_idx, cfg->nbits[0].nof_re, cfg->mimo_type, pdsch_scaling, noise_estimate)<0) { DEBUG("Error predecoding\n"); return SRSLTE_ERROR; diff --git a/lib/src/phy/phch/phich.c b/lib/src/phy/phch/phich.c index 6990d69e2..15aa4db88 100644 --- a/lib/src/phy/phch/phich.c +++ b/lib/src/phy/phch/phich.c @@ -239,7 +239,7 @@ int srslte_phich_decode(srslte_phich_t *q, cf_t *sf_symbols[SRSLTE_MAX_PORTS], /* in control channels, only diversity is supported */ if (q->cell.nof_ports == 1) { /* no need for layer demapping */ - srslte_predecoding_single_multi(q_sf_symbols, q_ce[0], q->d0, q->nof_rx_antennas, SRSLTE_PHICH_MAX_NSYMB, 1.0f, noise_estimate); + srslte_predecoding_single_multi(q_sf_symbols, q_ce[0], q->d0, NULL, q->nof_rx_antennas, SRSLTE_PHICH_MAX_NSYMB, 1.0f, noise_estimate); } else { srslte_predecoding_diversity_multi(q_sf_symbols, q_ce, x, q->nof_rx_antennas, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB, 1.0f); srslte_layerdemap_diversity(x, q->d0, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB / q->cell.nof_ports); diff --git a/lib/src/phy/phch/pmch.c b/lib/src/phy/phch/pmch.c index c1c322f34..c7ec0b204 100644 --- a/lib/src/phy/phch/pmch.c +++ b/lib/src/phy/phch/pmch.c @@ -378,7 +378,7 @@ int srslte_pmch_decode_multi(srslte_pmch_t *q, } // No tx diversity in MBSFN - srslte_predecoding_single_multi(q->symbols, q->ce[0], q->d, q->nof_rx_antennas, cfg->nbits[0].nof_re, 1.0f, noise_estimate); + srslte_predecoding_single_multi(q->symbols, q->ce[0], q->d, NULL, q->nof_rx_antennas, cfg->nbits[0].nof_re, 1.0f, noise_estimate); if (SRSLTE_VERBOSE_ISDEBUG()) { DEBUG("SAVED FILE subframe.dat: received subframe symbols\n"); diff --git a/lib/src/phy/phch/pucch.c b/lib/src/phy/phch/pucch.c index b1317de3e..dd3977757 100644 --- a/lib/src/phy/phch/pucch.c +++ b/lib/src/phy/phch/pucch.c @@ -787,7 +787,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, } // Equalization - srslte_predecoding_single(q->z_tmp, q->ce, q->z, nof_re, 1.0f, noise_estimate); + srslte_predecoding_single(q->z_tmp, q->ce, q->z, NULL, nof_re, 1.0f, noise_estimate); // Perform ML-decoding float corr=0, corr_max=-1e9; diff --git a/lib/src/phy/phch/pusch.c b/lib/src/phy/phch/pusch.c index feb4e8b4f..aa049f7c0 100644 --- a/lib/src/phy/phch/pusch.c +++ b/lib/src/phy/phch/pusch.c @@ -596,7 +596,7 @@ int srslte_pusch_decode(srslte_pusch_t *q, } // Equalization - srslte_predecoding_single(q->d, q->ce, q->z, cfg->nbits.nof_re, 1.0f, noise_estimate); + srslte_predecoding_single(q->d, q->ce, q->z, NULL, cfg->nbits.nof_re, 1.0f, noise_estimate); // DFT predecoding srslte_dft_precoding(&q->dft_precoding, q->z, q->d, cfg->grant.L_prb, cfg->nbits.nof_symb); From 8cabfa82cf80a40d5c0de822f5ab59abc69e0e6c Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 28 Feb 2018 12:30:34 +0100 Subject: [PATCH 143/342] Added CSI report enable option in SRS UE --- lib/include/srslte/interfaces/ue_interfaces.h | 1 + srsue/src/main.cc | 3 +++ srsue/src/phy/phch_worker.cc | 1 + srsue/ue.conf.example | 4 ++++ 4 files changed, 9 insertions(+) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index f18a6737b..735e1d02d 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -493,6 +493,7 @@ typedef struct { bool rssi_sensor_enabled; bool sic_pss_enabled; float rx_gain_offset; + bool pdsch_csi_enabled; } phy_args_t; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 1cac2092d..cce7568b1 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -269,6 +269,9 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { bpo::value(&args->expert.phy.estimator_fil_w)->default_value(0.1), "Chooses the coefficients for the 3-tap channel estimator centered filter.") + ("expert.pdsch_csi_enabled", + bpo::value(&args->expert.phy.pdsch_csi_enabled)->default_value(false), + "Stores the Channel State Information and uses it for weightening the softbits. It is only compatible with TM1.") ("rf_calibration.tx_corr_dc_gain", bpo::value(&args->rf_cal.tx_corr_dc_gain)->default_value(0.0), "TX DC offset gain correction") diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 6a533759b..ce4fb5d7f 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -137,6 +137,7 @@ bool phch_worker::init(uint32_t max_prb, srslte::log *log_h, srslte::log *log_ph srslte_chest_dl_cfo_estimate_enable(&ue_dl.chest, phy->args->cfo_ref_mask!=0, phy->args->cfo_ref_mask); srslte_ue_ul_set_normalization(&ue_ul, true); srslte_ue_ul_set_cfo_enable(&ue_ul, true); + srslte_pdsch_enable_csi(&ue_dl.pdsch, phy->args->pdsch_csi_enabled); mem_initiated = true; diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index b8cc43c2e..a288470d3 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -173,6 +173,9 @@ enable = false # cfo_loop_pss_timeout: After the PSS estimation is below cfo_loop_pss_tol for cfo_loop_pss_timeout times consecutively, # RS adjustments are allowed. # +# pdsch_csi_enabled: Stores the Channel State Information and uses it for weightening the softbits. It is only +# compatible with TM1. It is False by default. +# ##################################################################### [expert] #ip_netmask = 255.255.255.0 @@ -196,6 +199,7 @@ enable = false #pregenerate_signals = false #metrics_csv_enable = false #metrics_csv_filename = /tmp/ue_metrics.csv +#pdsch_csi_enabled = true # Caution! Only TM1 supported! # CFO related values #cfo_integer_enabled = false From fafed4a4a00f4ab5ac5162bb1f612fd7716f1065 Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 28 Feb 2018 17:58:47 +0000 Subject: [PATCH 144/342] small fix in mbsfn ofdm --- lib/src/phy/dft/ofdm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/phy/dft/ofdm.c b/lib/src/phy/dft/ofdm.c index e266023bb..977f37892 100644 --- a/lib/src/phy/dft/ofdm.c +++ b/lib/src/phy/dft/ofdm.c @@ -128,6 +128,8 @@ int srslte_ofdm_init_mbsfn_(srslte_ofdm_t *q, srslte_cp_t cp, cf_t *in_buffer, c if (sf_type == SRSLTE_SF_MBSFN) { q->mbsfn_subframe = true; q->non_mbsfn_region = 2; // default set to 2 + } else { + q->mbsfn_subframe = false; } return SRSLTE_SUCCESS; From a92a5d65f8ac38edd52fb1b2deafb2a86ea86c05 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 1 Mar 2018 12:30:47 +0100 Subject: [PATCH 145/342] Try to fix tx_end issue during HO --- srsue/src/phy/phch_recv.cc | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 6737f52e0..46973b125 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -397,16 +397,11 @@ bool phch_recv::cell_handover(srslte_cell_t cell) usleep(1000); cnt++; } - cnt = 0; - while(!is_in_idle_rx && cnt<20) { - usleep(1000); - cnt++; - } for(uint32_t i=0;iget_nof_workers();i++) { ((phch_worker*) workers_pool->get_worker(i))->reset(); } worker_com->reset(); - worker_com->reset_ul(); + radio_h->tx_end(); if (is_in_idle_rx) { Info("Cell HO: Reconfiguring cell\n"); if (set_cell()) { From fb53a515daac1f9d369e71a4ae8a9c0d393aa42a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 1 Mar 2018 12:48:14 +0100 Subject: [PATCH 146/342] Disable tx_end during HO --- srsue/src/phy/phch_recv.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 46973b125..68d7d6c3c 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -401,7 +401,7 @@ bool phch_recv::cell_handover(srslte_cell_t cell) ((phch_worker*) workers_pool->get_worker(i))->reset(); } worker_com->reset(); - radio_h->tx_end(); + //radio_h->tx_end(); if (is_in_idle_rx) { Info("Cell HO: Reconfiguring cell\n"); if (set_cell()) { From 2a69211f32a032918766d28a9fbdd624c11f1d2e Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 1 Mar 2018 13:59:01 +0100 Subject: [PATCH 147/342] SCH does not terminate all codeblocks if one fail. Also, SCH does not decode blocks with CRC=OK --- lib/include/srslte/phy/fec/softbuffer.h | 3 ++ lib/src/phy/fec/softbuffer.c | 46 ++++++++++++++++++++++--- lib/src/phy/phch/sch.c | 31 +++++++++++++---- 3 files changed, 69 insertions(+), 11 deletions(-) diff --git a/lib/include/srslte/phy/fec/softbuffer.h b/lib/include/srslte/phy/fec/softbuffer.h index a47cc7b96..3949134d8 100644 --- a/lib/include/srslte/phy/fec/softbuffer.h +++ b/lib/include/srslte/phy/fec/softbuffer.h @@ -42,6 +42,9 @@ typedef struct SRSLTE_API { uint32_t max_cb; int16_t **buffer_f; + uint8_t **data; + bool *cb_crc; + bool tb_crc; } srslte_softbuffer_rx_t; typedef struct SRSLTE_API { diff --git a/lib/src/phy/fec/softbuffer.c b/lib/src/phy/fec/softbuffer.c index 8efa937cb..9ed526825 100644 --- a/lib/src/phy/fec/softbuffer.c +++ b/lib/src/phy/fec/softbuffer.c @@ -47,32 +47,56 @@ int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t *q, uint32_t nof_prb) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { - ret = SRSLTE_ERROR; - bzero(q, sizeof(srslte_softbuffer_rx_t)); ret = srslte_ra_tbs_from_idx(26, nof_prb); if (ret != SRSLTE_ERROR) { q->max_cb = (uint32_t) ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1; + ret = SRSLTE_ERROR; q->buffer_f = srslte_vec_malloc(sizeof(int16_t*) * q->max_cb); if (!q->buffer_f) { perror("malloc"); - return SRSLTE_ERROR; + goto clean_exit; } + q->data = srslte_vec_malloc(sizeof(uint8_t*) * q->max_cb); + if (!q->data) { + perror("malloc"); + goto clean_exit; + } + + q->cb_crc = srslte_vec_malloc(sizeof(bool) * q->max_cb); + if (!q->cb_crc) { + perror("malloc"); + goto clean_exit; + } + bzero(q->cb_crc, sizeof(bool) * q->max_cb); + // FIXME: Use HARQ buffer limitation based on UE category for (uint32_t i=0;imax_cb;i++) { q->buffer_f[i] = srslte_vec_malloc(sizeof(int16_t) * SOFTBUFFER_SIZE); if (!q->buffer_f[i]) { perror("malloc"); - return SRSLTE_ERROR; + goto clean_exit; + } + + q->data[i] = srslte_vec_malloc(sizeof(uint8_t) * 6144/8); + if (!q->data[i]) { + perror("malloc"); + goto clean_exit; } } //srslte_softbuffer_rx_reset(q); ret = SRSLTE_SUCCESS; } } + + clean_exit: + if (ret != SRSLTE_SUCCESS) { + srslte_softbuffer_rx_free(q); + } + return ret; } @@ -86,6 +110,17 @@ void srslte_softbuffer_rx_free(srslte_softbuffer_rx_t *q) { } free(q->buffer_f); } + if (q->data) { + for (uint32_t i=0;imax_cb;i++) { + if (q->data[i]) { + free(q->data[i]); + } + } + free(q->data); + } + if (q->cb_crc) { + free(q->cb_crc); + } bzero(q, sizeof(srslte_softbuffer_rx_t)); } } @@ -110,6 +145,9 @@ void srslte_softbuffer_rx_reset_cb(srslte_softbuffer_rx_t *q, uint32_t nof_cb) { } } } + if (q->cb_crc) { + bzero(q->cb_crc, sizeof(bool) * q->max_cb); + } } diff --git a/lib/src/phy/phch/sch.c b/lib/src/phy/phch/sch.c index e6b7d49b9..b679e00f9 100644 --- a/lib/src/phy/phch/sch.c +++ b/lib/src/phy/phch/sch.c @@ -336,14 +336,17 @@ bool decode_tb_cb(srslte_sch_t *q, decoder_input[i] = NULL; } + uint32_t remaining_cb = 0; for (int i=0;icb_crc[i]; + if (softbuffer->cb_crc[i] == false) { + remaining_cb ++; + } } srslte_tdec_reset(&q->decoder, cb_len); - uint32_t remaining_cb = nof_cb; - q->nof_iterations = 0; while(remaining_cb>0) { @@ -401,7 +404,8 @@ bool decode_tb_cb(srslte_sch_t *q, // CRC is OK if (!srslte_crc_checksum_byte(crc_ptr, q->cb_in, len_crc)) { - memcpy(&data[(cb_idx[i]*rlen)/8], q->cb_in, rlen/8 * sizeof(uint8_t)); + memcpy(softbuffer->data[cb_idx[i]], q->cb_in, rlen/8 * sizeof(uint8_t)); + softbuffer->cb_crc[cb_idx[i]] = true; q->nof_iterations += srslte_tdec_get_nof_iterations_cb(&q->decoder, i); @@ -418,15 +422,28 @@ bool decode_tb_cb(srslte_sch_t *q, cb_idx[i], remaining_cb, i, first_cb, nof_cb); q->nof_iterations += q->max_iterations; - q->nof_iterations /= (nof_cb-remaining_cb+1); - return false; + srslte_tdec_reset_cb(&q->decoder, i); + remaining_cb--; + decoder_input[i] = NULL; + cb_idx[i] = 0; } } } } + softbuffer->tb_crc = true; + for (int i = 0; i < nof_cb && softbuffer->tb_crc; i++) { + /* If one CB failed return false */ + softbuffer->tb_crc = softbuffer->cb_crc[i]; + } + if (softbuffer->tb_crc) { + for (int i = 0; i < nof_cb; i++) { + memcpy(&data[i * rlen / 8], softbuffer->data[i], rlen/8 * sizeof(uint8_t)); + } + } + q->nof_iterations /= nof_cb; - return true; + return softbuffer->tb_crc; } /** From ec901373d4487b591c2a735677f8f251c05f2bfb Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 1 Mar 2018 13:58:04 +0100 Subject: [PATCH 148/342] Correction ofo simd.h for AVX512 --- lib/include/srslte/phy/utils/simd.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/include/srslte/phy/utils/simd.h b/lib/include/srslte/phy/utils/simd.h index 3b5a00a8a..3223c18a7 100644 --- a/lib/include/srslte/phy/utils/simd.h +++ b/lib/include/srslte/phy/utils/simd.h @@ -707,11 +707,13 @@ static inline void srslte_simd_cf_storeu(float *re, float *im, simd_cf_t simdreg static inline simd_f_t srslte_simd_cf_re(simd_cf_t in) { simd_f_t out = in.re; +#ifndef LV_HAVE_AVX512 #ifdef LV_HAVE_AVX2 /* Permute for AVX registers (mis SSE registers) */ const __m256i idx = _mm256_setr_epi32(0, 2, 4, 6, 1, 3, 5, 7); out = _mm256_permutevar8x32_ps(out, idx); #endif /* LV_HAVE_AVX2 */ +#endif /* LV_HAVE_AVX512 */ return out; } From 0fcb065ae8f50ae6ec23c823a4c2db8daa36d42a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Mar 2018 14:08:29 +0100 Subject: [PATCH 149/342] Disabled TX continuous and sleep on cell search --- srsue/hdr/mac/dl_harq.h | 13 +++++++------ srsue/hdr/phy/phch_common.h | 2 +- srsue/src/phy/phch_recv.cc | 1 + srsue/src/upper/nas.cc | 1 + 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index 9a7f66f47..261fb0d41 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -253,14 +253,14 @@ private: n_retx = 0; } - // Save grant - grant.last_ndi[tid] = cur_grant.ndi[tid]; - grant.last_tti = cur_grant.tti; - memcpy(&cur_grant, &grant, sizeof(Tgrant)); - // If data has not yet been successfully decoded if (!ack) { + // Save grant + grant.last_ndi[tid] = cur_grant.ndi[tid]; + grant.last_tti = cur_grant.tti; + memcpy(&cur_grant, &grant, sizeof(Tgrant)); + // Instruct the PHY To combine the received data and attempt to decode it if (pid == HARQ_BCCH_PID) { payload_buffer_ptr = harq_entity->demux_unit->request_buffer_bcch(cur_grant.n_bytes[tid]); @@ -281,7 +281,8 @@ private: } else { action->default_ack[tid] = true; - Warning("DL PID %d: Received duplicate TB. Discarting and retransmitting ACK\n", pid); + Warning("DL PID %d: Received duplicate TB. Discarting and retransmitting ACK (grant_tti=%d, ndi=%d, sz=%d)\n", + pid, cur_grant.tti, cur_grant.ndi[tid], cur_grant.n_bytes[tid]); } if (pid == HARQ_BCCH_PID || harq_entity->timer_aligment_timer->is_expired()) { diff --git a/srsue/hdr/phy/phch_common.h b/srsue/hdr/phy/phch_common.h index f21738b6b..e6ce10bc3 100644 --- a/srsue/hdr/phy/phch_common.h +++ b/srsue/hdr/phy/phch_common.h @@ -27,7 +27,7 @@ #ifndef UEPHYWORKERCOMMON_H #define UEPHYWORKERCOMMON_H -#define TX_MODE_CONTINUOUS 1 +#define TX_MODE_CONTINUOUS 0 #include diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 68d7d6c3c..7bb371db4 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -935,6 +935,7 @@ phch_recv::search::ret_code phch_recv::search::run(srslte_cell_t *cell) if (ret < 0) { Error("SYNC: Error decoding MIB: Error searching PSS\n"); + p->stop_rx(); return ERROR; } else if (ret == 0) { p->stop_rx(); diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 7f5683867..07d254cdc 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -173,6 +173,7 @@ void nas::plmn_search_end() { } else { nas_log->info("Finished searching PLMN in current EARFCN set but no networks were found.\n"); if (state == EMM_STATE_REGISTERED_INITIATED && plmn_selection == PLMN_NOT_SELECTED) { + sleep(1); rrc->plmn_search(); } } From de747f4e1c7ed50bdde2a0dd57e9c6ba15bf21f5 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Mar 2018 16:49:52 +0100 Subject: [PATCH 150/342] MUX retx Msg3 correctly --- srsue/hdr/mac/mux.h | 3 ++- srsue/src/mac/mux.cc | 23 ++++++++++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/srsue/hdr/mac/mux.h b/srsue/hdr/mac/mux.h index 889dd68f3..17a854711 100644 --- a/srsue/hdr/mac/mux.h +++ b/srsue/hdr/mac/mux.h @@ -104,7 +104,8 @@ private: /* Msg3 Buffer */ static const uint32_t MSG3_BUFF_SZ = 1024; uint8_t msg3_buff[MSG3_BUFF_SZ]; - + uint8_t *msg3_buff_start_pdu; + /* PDU Buffer */ srslte::sch_pdu pdu_msg; bool msg3_has_been_transmitted; diff --git a/srsue/src/mac/mux.cc b/srsue/src/mac/mux.cc index 2f8ade2af..59b94f085 100644 --- a/srsue/src/mac/mux.cc +++ b/srsue/src/mac/mux.cc @@ -46,8 +46,9 @@ mux::mux(uint8_t nof_harq_proc_) : pdu_msg(MAX_NOF_SUBHEADERS), pid_has_bsr(nof_ log_h = NULL; rlc = NULL; bsr_procedure = NULL; - phr_procedure = NULL; - + phr_procedure = NULL; + msg3_buff_start_pdu = NULL; + msg3_flush(); } @@ -347,6 +348,7 @@ void mux::msg3_flush() msg3_has_been_transmitted = false; msg3_pending = false; bzero(msg3_buff, sizeof(MSG3_BUFF_SZ)); + msg3_buff_start_pdu = NULL; } bool mux::msg3_is_transmitted() @@ -366,19 +368,22 @@ bool mux::msg3_is_pending() { uint8_t* mux::msg3_get(uint8_t *payload, uint32_t pdu_sz) { if (pdu_sz < MSG3_BUFF_SZ - 32) { - uint8_t* msg3_buff_start_pdu = pdu_get(msg3_buff, pdu_sz, 0, 0); if (!msg3_buff_start_pdu) { - Error("Moving PDU from Mux unit to Msg3 buffer\n"); - return NULL; + msg3_buff_start_pdu = pdu_get(msg3_buff, pdu_sz, 0, 0); + if (!msg3_buff_start_pdu) { + Error("Moving PDU from Mux unit to Msg3 buffer\n"); + return NULL; + } + msg3_has_been_transmitted = true; + msg3_pending = false; } - memcpy(payload, msg3_buff_start_pdu, sizeof(uint8_t)*pdu_sz); - msg3_has_been_transmitted = true; - msg3_pending = false; - return payload; } else { Error("Msg3 size (%d) is longer than internal msg3_buff size=%d, (see mux.h)\n", pdu_sz, MSG3_BUFF_SZ-32); return NULL; } + memcpy(payload, msg3_buff_start_pdu, sizeof(uint8_t)*pdu_sz); + msg3_has_been_transmitted = true; + return payload; } From fd0c8168f0ea7bda062eab1ecfa3e27d740834eb Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Mar 2018 20:59:17 +0100 Subject: [PATCH 151/342] Set to Continuous RX and TX --- lib/include/srslte/radio/radio.h | 11 ++- lib/src/phy/rf/rf_uhd_imp.c | 5 +- lib/src/radio/radio.cc | 21 ++--- lib/src/radio/radio_multi.cc | 7 +- srsenb/src/phy/txrx.cc | 4 +- srsue/hdr/phy/phch_common.h | 2 +- srsue/hdr/phy/phch_recv.h | 11 +-- srsue/hdr/upper/rrc.h | 2 +- srsue/src/phy/phch_recv.cc | 153 ++++++------------------------- srsue/src/phy/phch_worker.cc | 2 +- srsue/src/phy/phy.cc | 1 - srsue/src/upper/nas.cc | 1 - 12 files changed, 61 insertions(+), 159 deletions(-) diff --git a/lib/include/srslte/radio/radio.h b/lib/include/srslte/radio/radio.h index 454f1578f..143927730 100644 --- a/lib/include/srslte/radio/radio.h +++ b/lib/include/srslte/radio/radio.h @@ -72,6 +72,8 @@ namespace srslte { trace_enabled = false; tti = 0; agc_enabled = false; + radio_is_streaming = false; + is_initialized = false; }; bool init(char *args = NULL, char *devname = NULL, uint32_t nof_channels = 1); @@ -119,13 +121,13 @@ namespace srslte { void start_trace(); void write_trace(std::string filename); - void start_rx(bool now = false); - void stop_rx(); - + void set_tti(uint32_t tti); bool is_first_of_burst(); + bool is_init(); + void register_error_handler(srslte_rf_error_handler_t h); protected: @@ -168,6 +170,9 @@ namespace srslte { uint32_t tti; bool agc_enabled; + bool is_initialized = true;; + bool radio_is_streaming; + uint32_t saved_nof_channels; char saved_args[128]; char saved_devname[128]; diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index 0fc70c547..07eacbfb7 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -557,11 +557,12 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels) uhd_meta_range_free(&gain_range); // Start low priority thread to receive async commands - handler->async_thread_running = true; + /* + handler->async_thread_running = true; if (pthread_create(&handler->async_thread, NULL, async_thread, handler)) { perror("pthread_create"); return -1; - } + }*/ /* Restore priorities */ uhd_set_thread_priority(0, false); diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index f3baad4a5..aa7fa0d2c 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -71,7 +71,12 @@ bool radio::init(char *args, char *devname, uint32_t nof_channels) } saved_nof_channels = nof_channels; - return true; + is_initialized = true; + return true; +} + +bool radio::is_init() { + return is_initialized; } void radio::stop() @@ -141,6 +146,10 @@ bool radio::rx_at(void* buffer, uint32_t nof_samples, srslte_timestamp_t rx_time bool radio::rx_now(void* buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, srslte_timestamp_t* rxd_time) { + if (!radio_is_streaming) { + srslte_rf_start_rx_stream(&rf_device, true); + radio_is_streaming = true; + } if (srslte_rf_recv_with_time_multi(&rf_device, buffer, nof_samples, true, rxd_time?&rxd_time->full_secs:NULL, rxd_time?&rxd_time->frac_secs:NULL) > 0) { return true; @@ -446,16 +455,6 @@ void radio::set_tx_srate(double srate) tx_adv_sec = nsamples/cur_tx_srate; } -void radio::start_rx(bool now) -{ - srslte_rf_start_rx_stream(&rf_device, now); -} - -void radio::stop_rx() -{ - srslte_rf_stop_rx_stream(&rf_device); -} - void radio::register_error_handler(srslte_rf_error_handler_t h) { srslte_rf_register_error_handler(&rf_device, h); diff --git a/lib/src/radio/radio_multi.cc b/lib/src/radio/radio_multi.cc index 664458c75..df2cb4dfc 100644 --- a/lib/src/radio/radio_multi.cc +++ b/lib/src/radio/radio_multi.cc @@ -37,6 +37,7 @@ bool radio_multi::init_multi(uint32_t nof_rx_antennas, char* args, char* devname strncpy(saved_devname, devname, 127); } + is_initialized = true; return true; } @@ -46,7 +47,11 @@ bool radio_multi::rx_now(cf_t *buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, s for (int i=0;ifull_secs:NULL, rxd_time?&rxd_time->frac_secs:NULL) > 0) { return true; } else { diff --git a/srsenb/src/phy/txrx.cc b/srsenb/src/phy/txrx.cc index 7e97bd1af..fbc96ea72 100644 --- a/srsenb/src/phy/txrx.cc +++ b/srsenb/src/phy/txrx.cc @@ -104,9 +104,7 @@ void txrx::run_thread() log_h->info("Starting RX/TX thread nof_prb=%d, sf_len=%d\n",worker_com->cell.nof_prb, sf_len); - // Start streaming RX samples - radio_h->start_rx(); - + // Set TTI so that first TX is at tti=0 tti = 10235; diff --git a/srsue/hdr/phy/phch_common.h b/srsue/hdr/phy/phch_common.h index e6ce10bc3..f21738b6b 100644 --- a/srsue/hdr/phy/phch_common.h +++ b/srsue/hdr/phy/phch_common.h @@ -27,7 +27,7 @@ #ifndef UEPHYWORKERCOMMON_H #define UEPHYWORKERCOMMON_H -#define TX_MODE_CONTINUOUS 0 +#define TX_MODE_CONTINUOUS 1 #include diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index 1e15aea62..cea3004f6 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -95,7 +95,6 @@ private: void reset(); void radio_error(); - bool wait_radio_reset(); void set_ue_sync_opts(srslte_ue_sync_t *q, float cfo); void run_thread(); @@ -104,14 +103,7 @@ private: bool set_cell(); void cell_search_inc(); - void resync_sfn(bool restart_radio, bool restart_now = false); - bool stop_sync(); - void stop_rx(); - void start_rx(bool now = false); - bool radio_is_rx; - - bool radio_is_resetting; bool running; // Class to run cell search @@ -309,10 +301,9 @@ private: CELL_SELECT, CELL_MEASURE, CELL_CAMP, - IDLE_RX } phy_state; - bool is_in_idle, is_in_idle_rx; + bool is_in_idle; // Sampling rate mode (find is 1.96 MHz, camp is the full cell BW) enum { diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 1bfae16b3..926e2bebe 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -325,7 +325,7 @@ private: static const uint32_t RRC_PLMN_SELECT_TIMEOUT = 10000; uint32_t select_cell_timeout; - static const uint32_t RRC_SELECT_CELL_TIMEOUT = 2000; + static const uint32_t RRC_SELECT_CELL_TIMEOUT = 1000; uint8_t k_rrc_enc[32]; uint8_t k_rrc_int[32]; diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 7bb371db4..36614a0d1 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -134,7 +134,6 @@ void phch_recv::reset() srate_mode = SRATE_NONE; cell_search_in_progress = false; current_earfcn = 0; - radio_is_resetting = false; sfn_p.reset(); measure_p.reset(); search_p.reset(); @@ -145,7 +144,6 @@ void phch_recv::radio_error() { log_h->error("SYNC: Receiving from radio.\n"); phy_state = IDLE; - radio_is_resetting=true; // Need to find a method to effectively reset radio, reloading the driver does not work //radio_h->reset(); @@ -155,22 +153,12 @@ void phch_recv::radio_error() exit(-1); reset(); - radio_is_resetting=false; } void phch_recv::set_cfo(float cfo) { srslte_ue_sync_set_cfo_ref(&ue_sync, cfo); } -bool phch_recv::wait_radio_reset() { - int cnt=0; - while(cnt < 20 && radio_is_resetting) { - sleep(1); - cnt++; - } - return radio_is_resetting; -} - void phch_recv::set_agc_enable(bool enable) { do_agc = enable; @@ -265,24 +253,6 @@ bool phch_recv::set_cell() { return cell_is_set; } -void phch_recv::resync_sfn(bool restart_radio, bool restart_now) { - - if (restart_radio) { - wait_radio_reset(); - stop_rx(); - usleep(100000); - } - sfn_p.reset(); - search_p.reset(); - srslte_ue_sync_reset(&ue_sync); - - if (restart_radio) { - start_rx(restart_now); - } - - phy_state = CELL_SELECT; -} - void phch_recv::set_earfcn(std::vector earfcn) { this->earfcn = earfcn; } @@ -292,35 +262,14 @@ void phch_recv::force_freq(float dl_freq, float ul_freq) { this->ul_freq = ul_freq; } -bool phch_recv::stop_sync() { - - wait_radio_reset(); - - if (phy_state == IDLE && is_in_idle) { - return true; - } else { - Info("SYNC: Going to IDLE (state=%d)\n", phy_state); - phy_state = IDLE; - int cnt = 0; - while (!is_in_idle && cnt < 100) { - usleep(10000); - cnt++; - } - if (!is_in_idle) { - Warning("SYNC: Could not go to IDLE (state=%d)\n", phy_state); - } - return is_in_idle; - } -} - void phch_recv::reset_sync() { - if (phy_state != CELL_SELECT) { - Warning("SYNC: Resetting sync, cell_search_in_progress=%s\n", cell_search_in_progress?"yes":"no"); - resync_sfn(false); - } else { - Warning("SYNC: Trying to reset sync while in cell reselection\n"); - } + sfn_p.reset(); + search_p.reset(); + measure_p.reset(); + srslte_ue_sync_reset(&ue_sync); + + phy_state = CELL_SELECT; } void phch_recv::cell_search_inc() @@ -345,9 +294,6 @@ void phch_recv::cell_search_inc() void phch_recv::cell_search_next(bool reset) { if (cell_search_in_progress || reset) { cell_search_in_progress = false; - if (!stop_sync()) { - log_h->warning("SYNC: Couldn't stop PHY (state=%d)\n", phy_state); - } if (reset) { cur_earfcn_index = -1; } @@ -373,9 +319,6 @@ void phch_recv::cell_search_start() { void phch_recv::cell_search_stop() { Info("SYNC: Stopping Cell Search procedure...\n"); - if (!stop_sync()) { - Error("SYNC: Stopping cell search\n"); - } cell_search_in_progress = false; } @@ -391,9 +334,9 @@ bool phch_recv::cell_handover(srslte_cell_t cell) bool ret = false; this->cell = cell; Info("Cell HO: Stopping sync with current cell\n"); - phy_state = IDLE_RX; + phy_state = IDLE; cnt = 0; - while(!is_in_idle_rx && cnt<20) { + while(!is_in_idle && cnt<20) { usleep(1000); cnt++; } @@ -401,12 +344,11 @@ bool phch_recv::cell_handover(srslte_cell_t cell) ((phch_worker*) workers_pool->get_worker(i))->reset(); } worker_com->reset(); - //radio_h->tx_end(); - if (is_in_idle_rx) { + if (is_in_idle) { Info("Cell HO: Reconfiguring cell\n"); if (set_cell()) { - resync_sfn(false); Info("Cell HO: Synchronizing with new cell\n"); + phy_state = CELL_SELECT; ret = true; } else { log_h->error("Cell HO: Configuring cell PCI=%d\n", cell.id); @@ -428,18 +370,12 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { if (srate_mode != SRATE_CAMP) { set_sampling_rate(); } - if (phy_state < CELL_SELECT) { - resync_sfn(true, false); - } + phy_state = CELL_SELECT; return true; } else { cell_search_in_progress = false; - if (!stop_sync()) { - log_h->warning("Still not in idle\n"); - } - if (earfcn != current_earfcn) { if (set_frequency()) { log_h->error("Cell Select: Configuring cell in EARFCN=%d, PCI=%d\n", earfcn, cell.id); @@ -453,8 +389,7 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { if (set_cell()) { log_h->info("Cell Select: Synchronizing on cell...\n"); - - resync_sfn(true, false); + phy_state = CELL_SELECT; return true; } return false; @@ -522,22 +457,6 @@ void phch_recv::set_sampling_rate() } } -void phch_recv::stop_rx() { - if (radio_is_rx) { - Info("SYNC: Stopping RX streaming\n"); - radio_h->stop_rx(); - } - radio_is_rx = false; -} - -void phch_recv::start_rx(bool now) { - if (!radio_is_rx) { - Info("SYNC: Starting RX streaming\n"); - radio_h->start_rx(now); - } - radio_is_rx = true; -} - uint32_t phch_recv::get_current_tti() { return tti; } @@ -592,18 +511,19 @@ void phch_recv::run_thread() uint32_t sf_idx = 0; phy_state = IDLE; is_in_idle = true; - is_in_idle_rx = false; + + cf_t *dummy_buffer[SRSLTE_MAX_PORTS]; + + for (int i=0;istep(tti); log_phy_lib_h->step(tti); @@ -624,7 +544,7 @@ void phch_recv::run_thread() } if (set_cell()) { set_sampling_rate(); - resync_sfn(true, false); + phy_state = CELL_SELECT; } break; case search::CELL_NOT_FOUND: @@ -659,7 +579,7 @@ void phch_recv::run_thread() phy_state = CELL_SEARCH; } else { log_h->warning("SYNC: Timeout while synchronizing SFN. Reselecting cell\n"); - resync_sfn(false); + phy_state = CELL_SELECT; } break; case sfn_sync::IDLE: @@ -775,28 +695,18 @@ void phch_recv::run_thread() } break; case IDLE: - if (!is_in_idle) { - stop_rx(); - } - is_in_idle = true; - usleep(1000); - break; - case IDLE_RX: - if (!worker) { - worker = (phch_worker *) workers_pool->wait_worker(tti); - } - is_in_idle_rx = true; - if (worker) { - for (uint32_t i = 0; i < SRSLTE_MAX_PORTS; i++) { - buffer[i] = worker->get_buffer(i); + if (radio_h->is_init()) { + uint32_t nsamples = 1920; + if (current_srate > 0) { + nsamples = current_srate/1000; } - if (!radio_h->rx_now(buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb), NULL)) { - Error("SYNC: Receiving from radio while in IDLE_RX\n"); + if (!radio_h->rx_now(dummy_buffer, nsamples, NULL)) { + printf("SYNC: Receiving from radio while in IDLE_RX\n"); } } else { - // wait_worker() only returns NULL if it's being closed. Quit now to avoid unnecessary loops here - running = false; + usleep(1000); } + is_in_idle = true; break; } @@ -917,7 +827,6 @@ phch_recv::search::ret_code phch_recv::search::run(srslte_cell_t *cell) p->srate_mode = SRATE_FIND; p->radio_h->set_rx_srate(1.92e6); } - p->start_rx(); /* Find a cell in the given N_id_2 or go through the 3 of them to find the strongest */ uint32_t max_peak_cell = 0; @@ -935,10 +844,8 @@ phch_recv::search::ret_code phch_recv::search::run(srslte_cell_t *cell) if (ret < 0) { Error("SYNC: Error decoding MIB: Error searching PSS\n"); - p->stop_rx(); return ERROR; } else if (ret == 0) { - p->stop_rx(); Info("SYNC: Could not find any cell in this frequency\n"); return CELL_NOT_FOUND; } @@ -966,8 +873,6 @@ phch_recv::search::ret_code phch_recv::search::run(srslte_cell_t *cell) ret = srslte_ue_mib_sync_decode(&ue_mib_sync, 40, bch_payload, &cell->nof_ports, &sfn_offset); - p->stop_rx(); - if (ret == 1) { srslte_pbch_mib_unpack(bch_payload, cell, NULL); diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 6a533759b..cdfab95b9 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -1380,7 +1380,7 @@ void phch_worker::update_measurements() /* Only worker 0 reads the RSSI sensor every ~1-nof_cores s */ if (get_id() == 0) { - if (rssi_read_cnt) { + if (!rssi_read_cnt) { if (phy->get_radio()->has_rssi() && phy->args->rssi_sensor_enabled) { phy->last_radio_rssi = phy->get_radio()->get_rssi(); phy->rx_gain_offset = phy->avg_rssi_dbm - phy->last_radio_rssi + 30; diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index cf8ae33f8..3dfb5889a 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -366,7 +366,6 @@ void phy::reset() workers[i].reset(); } workers_common.reset(); - workers_common.reset_ul(); } uint32_t phy::get_current_tti() diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 07d254cdc..7f5683867 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -173,7 +173,6 @@ void nas::plmn_search_end() { } else { nas_log->info("Finished searching PLMN in current EARFCN set but no networks were found.\n"); if (state == EMM_STATE_REGISTERED_INITIATED && plmn_selection == PLMN_NOT_SELECTED) { - sleep(1); rrc->plmn_search(); } } From e64f3240cb83a9eec768fe78dbaadcaf3bc13a29 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Mar 2018 21:33:28 +0100 Subject: [PATCH 152/342] Disable tx_end before PRACH (not needed now?) --- srsue/src/phy/phch_recv.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 36614a0d1..3c2e4fc1e 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -657,10 +657,11 @@ void phch_recv::run_thread() tx_mutex_cnt = (tx_mutex_cnt+1) % nof_tx_mutex; // Reset Uplink TX buffer to avoid mixing packets in TX queue + /* if (prach_buffer->is_pending()) { Info("SYNC: PRACH pending: Reset UL\n"); - worker_com->reset_ul(); - } + radio_h->tx_end(); + }*/ // Check if we need to TX a PRACH if (prach_buffer->is_ready_to_send(tti)) { From df1a0c68e2ed2d37a6d82008545bccd5b8152e62 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Mar 2018 22:46:24 +0100 Subject: [PATCH 153/342] Disable ul_reset --- srsue/src/phy/phch_common.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_common.cc b/srsue/src/phy/phch_common.cc index 65681c8c6..3c3cf1641 100644 --- a/srsue/src/phy/phch_common.cc +++ b/srsue/src/phy/phch_common.cc @@ -355,13 +355,16 @@ void phch_common::reset() { void phch_common::reset_ul() { + /* is_first_tx = true; - is_first_of_burst = true; + is_first_of_burst = true; + for (uint32_t i=0;itx_end(); + */ } } From fea5c3462c17008512227a846ed923c19a75155c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 4 Mar 2018 11:15:51 +0100 Subject: [PATCH 154/342] Start RX with delay --- lib/src/radio/radio.cc | 2 +- lib/src/radio/radio_multi.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index aa7fa0d2c..ba2b1d1f0 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -147,7 +147,7 @@ bool radio::rx_at(void* buffer, uint32_t nof_samples, srslte_timestamp_t rx_time bool radio::rx_now(void* buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, srslte_timestamp_t* rxd_time) { if (!radio_is_streaming) { - srslte_rf_start_rx_stream(&rf_device, true); + srslte_rf_start_rx_stream(&rf_device, false); radio_is_streaming = true; } if (srslte_rf_recv_with_time_multi(&rf_device, buffer, nof_samples, true, diff --git a/lib/src/radio/radio_multi.cc b/lib/src/radio/radio_multi.cc index df2cb4dfc..ff0a036a2 100644 --- a/lib/src/radio/radio_multi.cc +++ b/lib/src/radio/radio_multi.cc @@ -48,7 +48,7 @@ bool radio_multi::rx_now(cf_t *buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, s ptr[i] = buffer[i]; } if (!radio_is_streaming) { - srslte_rf_start_rx_stream(&rf_device, true); + srslte_rf_start_rx_stream(&rf_device, false); radio_is_streaming = true; } if (srslte_rf_recv_with_time_multi(&rf_device, ptr, nof_samples, true, From 650f43353267982d3c7d9f4724b51e2c950c9443 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 4 Mar 2018 11:55:31 +0100 Subject: [PATCH 155/342] Add mutex to worker_imp/set_cell worker --- srsue/hdr/phy/phch_worker.h | 3 ++- srsue/src/phy/phch_worker.cc | 27 +++++++++++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index 78389ccf7..167334918 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -119,7 +119,8 @@ private: struct timeval tr_time[3]; srslte::trace tr_exec; bool trace_enabled; - + + pthread_mutex_t mutex; /* Common objects */ phch_common *phy; diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index cdfab95b9..f8b9e8148 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -86,6 +86,7 @@ phch_worker::~phch_worker() void phch_worker::reset() { + pthread_mutex_lock(&mutex); bzero(&dl_metrics, sizeof(dl_metrics_t)); bzero(&ul_metrics, sizeof(ul_metrics_t)); bzero(&dmrs_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t)); @@ -101,6 +102,7 @@ void phch_worker::reset() I_sr = 0; cfi = 0; rssi_read_cnt = 0; + pthread_mutex_unlock(&mutex); } void phch_worker::set_common(phch_common* phy_) @@ -140,29 +142,35 @@ bool phch_worker::init(uint32_t max_prb, srslte::log *log_h, srslte::log *log_ph mem_initiated = true; + pthread_mutex_init(&mutex, NULL); return true; } bool phch_worker::set_cell(srslte_cell_t cell_) { + bool ret = false; + pthread_mutex_lock(&mutex); if (cell.id != cell_.id || !cell_initiated) { memcpy(&cell, &cell_, sizeof(srslte_cell_t)); if (srslte_ue_dl_set_cell(&ue_dl, cell)) { Error("Initiating UE DL\n"); - return false; + goto unlock; } if (srslte_ue_ul_set_cell(&ue_ul, cell)) { Error("Initiating UE UL\n"); - return false; + goto unlock; } srslte_ue_ul_set_normalization(&ue_ul, true); srslte_ue_ul_set_cfo_enable(&ue_ul, true); cell_initiated = true; } - return true; + ret = true; +unlock: + pthread_mutex_unlock(&mutex); + return ret; } cf_t* phch_worker::get_buffer(uint32_t antenna_idx) @@ -193,9 +201,11 @@ void phch_worker::set_sample_offset(float sample_offset) void phch_worker::set_crnti(uint16_t rnti) { + pthread_mutex_lock(&mutex); srslte_ue_dl_set_rnti(&ue_dl, rnti); srslte_ue_ul_set_rnti(&ue_ul, rnti); - rnti_is_set = true; + rnti_is_set = true; + pthread_mutex_unlock(&mutex); } float phch_worker::get_ref_cfo() @@ -243,7 +253,9 @@ void phch_worker::work_imp() if (!cell_initiated) { return; } - + + pthread_mutex_lock(&mutex); + Debug("TTI %d running\n", tti); #ifdef LOG_EXECTIME @@ -412,7 +424,9 @@ void phch_worker::work_imp() chest_loop->out_of_sync(); } } - + + pthread_mutex_unlock(&mutex); + /* Tell the plotting thread to draw the plots */ #ifdef ENABLE_GUI if ((int) get_id() == plot_worker_id) { @@ -1211,6 +1225,7 @@ void phch_worker::enable_pregen_signals(bool enabled) void phch_worker::set_ul_params(bool pregen_disabled) { + phy_interface_rrc::phy_cfg_common_t *common = &phy->config->common; LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *dedicated = &phy->config->dedicated; From 91664ef2beef186ef2717b0003da3afe9de839b0 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 4 Mar 2018 11:55:58 +0100 Subject: [PATCH 156/342] Do sell reselection on IDLE by phch_recv thread instead of worker --- lib/include/srslte/interfaces/ue_interfaces.h | 2 +- srsue/hdr/phy/phch_recv.h | 7 +++++- srsue/hdr/phy/phy.h | 2 +- srsue/src/phy/phch_recv.cc | 24 ++++++++++++++----- srsue/src/phy/phy.cc | 4 ++-- srsue/src/upper/rrc.cc | 22 +++++++---------- 6 files changed, 36 insertions(+), 25 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index f18a6737b..52d11416c 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -582,7 +582,7 @@ public: virtual void cell_search_start() = 0; virtual void cell_search_stop() = 0; virtual void cell_search_next() = 0; - virtual bool cell_select(uint32_t earfcn, srslte_cell_t cell) = 0; + virtual void cell_select(uint32_t earfcn, srslte_cell_t cell) = 0; virtual bool cell_handover(srslte_cell_t cell) = 0; /* Is the PHY downlink synchronized? */ diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index cea3004f6..b5848a6b3 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -63,7 +63,7 @@ public: void cell_search_start(); void cell_search_stop(); void cell_search_next(bool reset = false); - bool cell_select(uint32_t earfcn, srslte_cell_t cell); + void cell_select(uint32_t earfcn, srslte_cell_t cell); bool cell_handover(srslte_cell_t cell); void meas_reset(); @@ -103,6 +103,10 @@ private: bool set_cell(); void cell_search_inc(); + void cell_reselect(); + + uint32_t new_earfcn; + srslte_cell_t new_cell; bool running; @@ -299,6 +303,7 @@ private: IDLE = 0, CELL_SEARCH, CELL_SELECT, + CELL_RESELECT, CELL_MEASURE, CELL_CAMP, } phy_state; diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index a29480ad4..9270973c0 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -87,7 +87,7 @@ public: void cell_search_start(); void cell_search_stop(); void cell_search_next(); - bool cell_select(uint32_t earfcn, srslte_cell_t phy_cell); + void cell_select(uint32_t earfcn, srslte_cell_t phy_cell); bool cell_handover(srslte_cell_t cell); void meas_reset(); diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 3c2e4fc1e..7a3efeab7 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -361,9 +361,21 @@ bool phch_recv::cell_handover(srslte_cell_t cell) return ret; } -bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { +/* interface from higher layers to select a new cell */ +void phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { - // Check if we are already camping in this cell + new_earfcn = earfcn; + new_cell = cell; + phy_state = CELL_RESELECT; +} + +/* Perform cell (re)-selection on IDLE or CAMP */ +void phch_recv::cell_reselect() +{ + uint32_t earfcn = new_earfcn; + srslte_cell_t cell = new_cell; + + // If we are already in the new cell, just resynchronize if (earfcn == current_earfcn && this->cell.id == cell.id) { log_h->info("Cell Select: Already in cell EARFCN=%d\n", earfcn); cell_search_in_progress = false; @@ -371,15 +383,14 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { set_sampling_rate(); } phy_state = CELL_SELECT; - return true; } else { + /* If we are going to a new cell, configure it */ cell_search_in_progress = false; if (earfcn != current_earfcn) { if (set_frequency()) { log_h->error("Cell Select: Configuring cell in EARFCN=%d, PCI=%d\n", earfcn, cell.id); - return false; } current_earfcn = earfcn; } @@ -390,9 +401,7 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { if (set_cell()) { log_h->info("Cell Select: Synchronizing on cell...\n"); phy_state = CELL_SELECT; - return true; } - return false; } } @@ -559,6 +568,9 @@ void phch_recv::run_thread() } } break; + case CELL_RESELECT: + cell_reselect(); + break; case CELL_SELECT: switch (sfn_p.run_subframe(&cell, &tti)) { diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 3dfb5889a..a2d517a02 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -282,9 +282,9 @@ int phy::meas_stop(uint32_t earfcn, int pci) { return sf_recv.meas_stop(earfcn, pci); } -bool phy::cell_select(uint32_t earfcn, srslte_cell_t phy_cell) +void phy::cell_select(uint32_t earfcn, srslte_cell_t phy_cell) { - return sf_recv.cell_select(earfcn, phy_cell); + sf_recv.cell_select(earfcn, phy_cell); } bool phy::cell_handover(srslte_cell_t cell) { diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index dfb356b92..1aecb273b 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -525,20 +525,14 @@ void rrc::select_next_cell_in_plmn() { neighbour_cells[i]->in_sync) // matches S criteria { // Try to select Cell - if (phy->cell_select(neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->phy_cell)) { - set_serving_cell(i); - rrc_log->info("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", - serving_cell->phy_cell.id, serving_cell->get_earfcn(), - serving_cell->get_cell_id()); - rrc_log->console("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", - serving_cell->phy_cell.id, serving_cell->get_earfcn(), - serving_cell->get_cell_id()); - } else { - // Set to out-of-sync if can't synchronize - neighbour_cells[i]->in_sync = false; - rrc_log->warning("Selecting cell EARFCN=%d, Cell ID=0x%x.\n", - neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->get_cell_id()); - } + phy->cell_select(neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->phy_cell); + set_serving_cell(i); + rrc_log->info("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", + serving_cell->phy_cell.id, serving_cell->get_earfcn(), + serving_cell->get_cell_id()); + rrc_log->console("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", + serving_cell->phy_cell.id, serving_cell->get_earfcn(), + serving_cell->get_cell_id()); return; } } From ed52604d3001e0237eb6f2a0b89cd990c2f988c9 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 4 Mar 2018 21:51:14 +0100 Subject: [PATCH 157/342] Restart rx_stream on radio error --- lib/src/radio/radio.cc | 7 ++----- srsue/src/phy/phch_recv.cc | 12 +++--------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index ba2b1d1f0..7008790a3 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -87,11 +87,8 @@ void radio::stop() void radio::reset() { printf("Resetting Radio...\n"); - srslte_rf_close(&rf_device); - sleep(3); - if (srslte_rf_open_devname(&rf_device, saved_devname, saved_args, saved_nof_channels)) { - fprintf(stderr, "Error opening RF device\n"); - } + srslte_rf_stop_rx_stream(&rf_device); + radio_is_streaming = false; } void radio::set_manual_calibration(rf_cal_t* calibration) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 7a3efeab7..a6f1a5d84 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -143,16 +143,10 @@ void phch_recv::reset() void phch_recv::radio_error() { log_h->error("SYNC: Receiving from radio.\n"); - phy_state = IDLE; - - // Need to find a method to effectively reset radio, reloading the driver does not work - //radio_h->reset(); - radio_h->stop(); - - fprintf(stdout, "Error while receiving samples. Restart srsUE\n"); - exit(-1); - + phy_state = CELL_SEARCH; reset(); + // Need to find a method to effectively reset radio, reloading the driver does not work + radio_h->reset(); } void phch_recv::set_cfo(float cfo) { From b257ab96bf8ba407ae322e61dd2c8be1c1dee193 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 4 Mar 2018 21:51:32 +0100 Subject: [PATCH 158/342] Locking on worker::reset() causes dead-lock --- srsue/src/phy/phch_worker.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index f8b9e8148..3075b0b30 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -86,7 +86,6 @@ phch_worker::~phch_worker() void phch_worker::reset() { - pthread_mutex_lock(&mutex); bzero(&dl_metrics, sizeof(dl_metrics_t)); bzero(&ul_metrics, sizeof(ul_metrics_t)); bzero(&dmrs_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t)); @@ -102,7 +101,6 @@ void phch_worker::reset() I_sr = 0; cfi = 0; rssi_read_cnt = 0; - pthread_mutex_unlock(&mutex); } void phch_worker::set_common(phch_common* phy_) From 3dddae0566a6e8eefda35c71421196aa520bb732 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 22 Feb 2018 12:18:29 +0100 Subject: [PATCH 159/342] rrc: check pool buffer allocation and handle error --- srsue/src/upper/rrc.cc | 43 +++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 1aecb273b..cade0e306 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1529,10 +1529,13 @@ byte_buffer_t* rrc::byte_align_and_pack(byte_buffer_t *pdu) pdcp_buf = pool_allocate; } - srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits); - pdcp_buf->N_bytes = bit_buf.N_bits / 8; - pdcp_buf->set_timestamp(); - + if (pdcp_buf != NULL) { + srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits); + pdcp_buf->N_bytes = bit_buf.N_bits / 8; + pdcp_buf->set_timestamp(); + } else { + rrc_log->error("Fatal Error: Couldn't allocate PDU in byte_align_and_pack().\n"); + } return pdcp_buf; } @@ -1540,20 +1543,21 @@ void rrc::send_ul_ccch_msg(byte_buffer_t *pdu) { liblte_rrc_pack_ul_ccch_msg(&ul_ccch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); pdu = byte_align_and_pack(pdu); + if (pdu) { + // Set UE contention resolution ID in MAC + uint64_t uecri = 0; + uint8_t *ue_cri_ptr = (uint8_t *) &uecri; + uint32_t nbytes = 6; + for (uint32_t i = 0; i < nbytes; i++) { + ue_cri_ptr[nbytes - i - 1] = pdu->msg[i]; + } - // Set UE contention resolution ID in MAC - uint64_t uecri = 0; - uint8_t *ue_cri_ptr = (uint8_t *) &uecri; - uint32_t nbytes = 6; - for (uint32_t i = 0; i < nbytes; i++) { - ue_cri_ptr[nbytes - i - 1] = pdu->msg[i]; - } - - rrc_log->debug("Setting UE contention resolution ID: %d\n", uecri); - mac->set_contention_id(uecri); + rrc_log->debug("Setting UE contention resolution ID: %d\n", uecri); + mac->set_contention_id(uecri); - rrc_log->info("Sending %s\n", liblte_rrc_ul_ccch_msg_type_text[ul_ccch_msg.msg_type]); - pdcp->write_sdu(RB_ID_SRB0, pdu); + rrc_log->info("Sending %s\n", liblte_rrc_ul_ccch_msg_type_text[ul_ccch_msg.msg_type]); + pdcp->write_sdu(RB_ID_SRB0, pdu); + } } void rrc::send_ul_dcch_msg(byte_buffer_t *pdu) @@ -1561,9 +1565,10 @@ void rrc::send_ul_dcch_msg(byte_buffer_t *pdu) liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); pdu = byte_align_and_pack(pdu); - - rrc_log->info("Sending %s\n", liblte_rrc_ul_dcch_msg_type_text[ul_dcch_msg.msg_type]); - pdcp->write_sdu(RB_ID_SRB1, pdu); + if (pdu) { + rrc_log->info("Sending %s\n", liblte_rrc_ul_dcch_msg_type_text[ul_dcch_msg.msg_type]); + pdcp->write_sdu(RB_ID_SRB1, pdu); + } } void rrc::write_sdu(uint32_t lcid, byte_buffer_t *sdu) { From a85288566bb7786856a058db44f0b4bf6c3d90e9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 22 Feb 2018 13:51:20 +0100 Subject: [PATCH 160/342] print summary about allocated buffers when buffer pool is full --- lib/include/srslte/common/buffer_pool.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index e48144b6f..4edc50fc6 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include /******************************************************************************* @@ -76,8 +78,13 @@ public: { printf("%d buffers in queue\n", (int) used.size()); #ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED + std::map buffer_cnt; for (uint32_t i=0;idebug_name)?used[i]->debug_name:"Undefined"); + buffer_cnt[strlen(used[i]->debug_name)?used[i]->debug_name:"Undefined"]++; + } + std::map::iterator it; + for (it = buffer_cnt.begin(); it != buffer_cnt.end(); it++) { + printf(" - %dx %s\n", it->second, it->first.c_str()); } #endif } From 507ce037bfa756e4c9843757fa104c7ee949ed4e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 22 Feb 2018 14:07:27 +0100 Subject: [PATCH 161/342] parameterize RLC AM stress tester and add to ctest suite --- lib/test/upper/CMakeLists.txt | 3 +- lib/test/upper/rlc_am_stress_test.cc | 71 +++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/lib/test/upper/CMakeLists.txt b/lib/test/upper/CMakeLists.txt index 8793118e7..79bbb8331 100644 --- a/lib/test/upper/CMakeLists.txt +++ b/lib/test/upper/CMakeLists.txt @@ -31,7 +31,8 @@ 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) +target_link_libraries(rlc_am_stress_test srslte_upper srslte_phy srslte_common ${Boost_LIBRARIES}) +add_test(rlc_am_stress_test rlc_am_stress_test --duration 10) add_executable(rlc_um_data_test rlc_um_data_test.cc) target_link_libraries(rlc_um_data_test srslte_upper srslte_phy srslte_common) diff --git a/lib/test/upper/rlc_am_stress_test.cc b/lib/test/upper/rlc_am_stress_test.cc index 137236b4a..c5cf4e877 100644 --- a/lib/test/upper/rlc_am_stress_test.cc +++ b/lib/test/upper/rlc_am_stress_test.cc @@ -31,23 +31,66 @@ #include "srslte/common/logger_stdout.h" #include "srslte/common/threads.h" #include "srslte/upper/rlc.h" +#include +#include #include -#define NBUFS 5 +using namespace std; using namespace srsue; using namespace srslte; +namespace bpo = boost::program_options; + +typedef struct { + uint32_t test_duration_sec; + float error_rate; + uint32_t sdu_gen_delay_usec; +} stress_test_args_t; + +void parse_args(stress_test_args_t *args, int argc, char *argv[]) { + + // Command line only options + bpo::options_description general("General options"); + + general.add_options() + ("help,h", "Produce help message") + ("version,v", "Print version information and exit"); + + // Command line or config file options + bpo::options_description common("Configuration options"); + common.add_options() + ("duration", bpo::value(&args->test_duration_sec)->default_value(10), "Duration (sec)") + ("sdu_gen_delay", bpo::value(&args->sdu_gen_delay_usec)->default_value(10), "SDU generation delay (usec)") + ("error_rate", bpo::value(&args->error_rate)->default_value(0.1), "Rate at which RLC PDUs are dropped"); + + // these options are allowed on the command line + bpo::options_description cmdline_options; + cmdline_options.add(common).add(general); + + // parse the command line and store result in vm + bpo::variables_map vm; + bpo::store(bpo::command_line_parser(argc, argv).options(cmdline_options).run(), vm); + bpo::notify(vm); + + // help option was given - print usage and exit + if (vm.count("help")) { + cout << "Usage: " << argv[0] << " [OPTIONS] config_file" << endl << endl; + cout << common << endl << general << endl; + exit(0); + } +} class mac_reader :public thread { public: - mac_reader(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_) + mac_reader(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_, uint32_t sdu_gen_delay_usec_) { rlc1 = rlc1_; rlc2 = rlc2_; fail_rate = fail_rate_; run_enable = true; running = false; + sdu_gen_delay_usec = sdu_gen_delay_usec_; } void stop() @@ -82,7 +125,7 @@ private: if(((float)rand()/RAND_MAX > fail_rate) && read>0) { rlc2->write_pdu(1, pdu->msg, opp_size); } - usleep(100); + usleep(sdu_gen_delay_usec); } running = false; byte_buffer_pool::get_instance()->deallocate(pdu); @@ -91,6 +134,7 @@ private: rlc_interface_mac *rlc1; rlc_interface_mac *rlc2; float fail_rate; + uint32_t sdu_gen_delay_usec; bool run_enable; bool running; @@ -100,9 +144,9 @@ 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_) + mac_dummy(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_, uint32_t sdu_gen_delay_usec_) + :r1(rlc1_, rlc2_, fail_rate_, sdu_gen_delay_usec_) + ,r2(rlc2_, rlc1_, fail_rate_, sdu_gen_delay_usec_) { } @@ -191,7 +235,7 @@ private: pdu->N_bytes = 1500; pdu->msg[0] = sn++; rlc->write_sdu(1, pdu); - usleep(100); + usleep(10); } running = false; } @@ -205,7 +249,7 @@ private: rlc_interface_pdcp *rlc; }; -void stress_test() +void stress_test(stress_test_args_t args) { srslte::log_filter log1("RLC_AM_1"); srslte::log_filter log2("RLC_AM_2"); @@ -214,14 +258,12 @@ void stress_test() log1.set_hex_limit(-1); log2.set_hex_limit(-1); - float fail_rate = 0.1; - rlc rlc1; rlc rlc2; rlc_am_tester tester1(&rlc1, "tester1"); rlc_am_tester tester2(&rlc2, "tester2"); - mac_dummy mac(&rlc1, &rlc2, fail_rate); + mac_dummy mac(&rlc1, &rlc2, args.error_rate, args.sdu_gen_delay_usec); ue_interface ue; rlc1.init(&tester1, &tester1, &ue, &log1, &mac, 0); @@ -245,7 +287,7 @@ void stress_test() tester2.start(7); mac.start(); - usleep(100e6); + usleep(args.test_duration_sec * 1e6); tester1.stop(); tester2.stop(); @@ -254,6 +296,9 @@ void stress_test() int main(int argc, char **argv) { - stress_test(); + stress_test_args_t args; + parse_args(&args, argc, argv); + + stress_test(args); byte_buffer_pool::get_instance()->cleanup(); } From 2c85da3e4ba41ec5d4f82532de8faf9e227a23e5 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 13:18:38 +0100 Subject: [PATCH 162/342] initilize variable in log_filter --- lib/src/common/log_filter.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/common/log_filter.cc b/lib/src/common/log_filter.cc index b498d466c..8b72a3c2b 100644 --- a/lib/src/common/log_filter.cc +++ b/lib/src/common/log_filter.cc @@ -40,6 +40,7 @@ log_filter::log_filter() do_tti = false; time_src = NULL; time_format = TIME; + logger_h = NULL; } log_filter::log_filter(std::string layer) From f60a9eab415ac08bb8c5e2e8591d3207d1abe058 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 13:20:34 +0100 Subject: [PATCH 163/342] initialize RF UHD handler in init --- lib/src/phy/rf/rf_uhd_imp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index 07eacbfb7..a1bec2657 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -334,11 +334,12 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels) perror("malloc"); return -1; } + bzero(handler, sizeof(rf_uhd_handler_t)); *h = handler; - + /* Set priority to UHD threads */ uhd_set_thread_priority(uhd_default_thread_priority, true); - + /* Find available devices */ uhd_string_vector_handle devices_str; uhd_string_vector_make(&devices_str); From 4a279150224c54cc5f76cd426613aef11a25cae0 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 13:21:58 +0100 Subject: [PATCH 164/342] bzero dft object during init, add call to fftw_cleanup in dft_exit --- lib/src/phy/dft/dft_fftw.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/phy/dft/dft_fftw.c b/lib/src/phy/dft/dft_fftw.c index e6eb70ecf..ede6ce69b 100644 --- a/lib/src/phy/dft/dft_fftw.c +++ b/lib/src/phy/dft/dft_fftw.c @@ -58,10 +58,12 @@ void srslte_dft_exit() { #ifdef FFTW_WISDOM_FILE fftwf_export_wisdom_to_filename(FFTW_WISDOM_FILE); #endif + fftwf_cleanup(); } int srslte_dft_plan(srslte_dft_plan_t *plan, const int dft_points, srslte_dft_dir_t dir, srslte_dft_mode_t mode) { + bzero(plan, sizeof(srslte_dft_plan_t)); if(mode == SRSLTE_DFT_COMPLEX){ return srslte_dft_plan_c(plan,dft_points,dir); } else { From 1efcea7e47f88e5fde2b06eec1ee81c3c6e347c8 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 13:29:10 +0100 Subject: [PATCH 165/342] call dft_exit in various tests --- lib/src/phy/dft/test/ofdm_test.c | 3 +++ lib/src/phy/utils/test/dft_test.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/lib/src/phy/dft/test/ofdm_test.c b/lib/src/phy/dft/test/ofdm_test.c index e77fcd39e..c40be4d0a 100644 --- a/lib/src/phy/dft/test/ofdm_test.c +++ b/lib/src/phy/dft/test/ofdm_test.c @@ -171,5 +171,8 @@ int main(int argc, char **argv) { n_prb++; } + + srslte_dft_exit(); + exit(0); } diff --git a/lib/src/phy/utils/test/dft_test.c b/lib/src/phy/utils/test/dft_test.c index fd5a308a7..b880f8027 100644 --- a/lib/src/phy/utils/test/dft_test.c +++ b/lib/src/phy/utils/test/dft_test.c @@ -157,6 +157,8 @@ int main(int argc, char **argv) { if(test_dft(in) != 0) return -1; + srslte_dft_exit(); + free(in); printf("Done\n"); exit(0); From 57bb831f27c4eb005039b991ef9e80758e67d08d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 13:32:21 +0100 Subject: [PATCH 166/342] fix RM turbo test --- lib/src/phy/fec/test/rm_turbo_test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/phy/fec/test/rm_turbo_test.c b/lib/src/phy/fec/test/rm_turbo_test.c index 1c5b2abf5..c8a0a95b5 100644 --- a/lib/src/phy/fec/test/rm_turbo_test.c +++ b/lib/src/phy/fec/test/rm_turbo_test.c @@ -198,6 +198,8 @@ int main(int argc, char **argv) { } srslte_rm_turbo_free_tables(); + free(rm_bits_s); + free(rm_bits_f); free(rm_bits); free(rm_bits2); free(rm_bits2_bytes); From 281611b26aabb1bffc2407e5b80d20206bc0c065 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 13:45:49 +0100 Subject: [PATCH 167/342] allow n param in pss_usrp test --- lib/src/phy/sync/test/pss_usrp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/sync/test/pss_usrp.c b/lib/src/phy/sync/test/pss_usrp.c index d82555c95..08afdd025 100644 --- a/lib/src/phy/sync/test/pss_usrp.c +++ b/lib/src/phy/sync/test/pss_usrp.c @@ -74,7 +74,7 @@ void usage(char *prog) { void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "adgetvsfil")) != -1) { + while ((opt = getopt(argc, argv, "adgetvnsfil")) != -1) { switch (opt) { case 'a': rf_args = argv[optind]; From f6ee0e1c8a49f53c0c27eacd902288ae14045349 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 15:47:14 +0100 Subject: [PATCH 168/342] move byte_buffer to UE base class --- srsue/hdr/ue.h | 2 -- srsue/hdr/ue_base.h | 5 ++++- srsue/src/ue.cc | 2 -- srsue/src/ue_base.cc | 6 ++++++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index e36277461..e6c66b540 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -110,8 +110,6 @@ private: srslte::log_filter gw_log; srslte::log_filter usim_log; - srslte::byte_buffer_pool *pool; - all_args_t *args; bool started; diff --git a/srsue/hdr/ue_base.h b/srsue/hdr/ue_base.h index 256813d5f..201f63843 100644 --- a/srsue/hdr/ue_base.h +++ b/srsue/hdr/ue_base.h @@ -146,7 +146,7 @@ class ue_base { public: ue_base(); - virtual ~ue_base() {} + virtual ~ue_base(); static ue_base* get_instance(srsue_instance_type_t type); @@ -173,6 +173,9 @@ public: std::string get_build_mode(); std::string get_build_info(); std::string get_build_string(); + +private: + srslte::byte_buffer_pool *pool; }; } // namespace srsue diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 2f8fa5794..1de1ddbd0 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -40,12 +40,10 @@ namespace srsue{ ue::ue() :started(false) { - pool = byte_buffer_pool::get_instance(); } ue::~ue() { - byte_buffer_pool::cleanup(); } bool ue::init(all_args_t *args_) diff --git a/srsue/src/ue_base.cc b/srsue/src/ue_base.cc index 4b2c372ae..a4264a099 100644 --- a/srsue/src/ue_base.cc +++ b/srsue/src/ue_base.cc @@ -64,6 +64,12 @@ ue_base::ue_base() { // load FFTW wisdom srslte_dft_load(); + + pool = byte_buffer_pool::get_instance(); +} + +ue_base::~ue_base() { + byte_buffer_pool::cleanup(); } void ue_base::cleanup(void) From 8fcf25360eab03c6c70ceca2e091b92c020473c6 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 15:48:38 +0100 Subject: [PATCH 169/342] fix missing newline --- srsue/src/phy/phch_recv.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index a6f1a5d84..81c964a7b 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -954,7 +954,7 @@ phch_recv::sfn_sync::ret_code phch_recv::sfn_sync::run_subframe(srslte_cell_t *c srslte_ue_sync_decode_sss_on_track(ue_sync, true); int ret = srslte_ue_sync_zerocopy_multi(ue_sync, buffer); if (ret < 0) { - Error("SYNC: Error calling ue_sync_get_buffer"); + Error("SYNC: Error calling ue_sync_get_buffer.\n"); return ERROR; } From 20e6ed102e03880dc702ba25d79845a431896d9b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 15:50:22 +0100 Subject: [PATCH 170/342] fix when accessing uninitialized file --- lib/src/common/logger_file.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/common/logger_file.cc b/lib/src/common/logger_file.cc index 25155da08..a911ae20e 100644 --- a/lib/src/common/logger_file.cc +++ b/lib/src/common/logger_file.cc @@ -35,6 +35,7 @@ namespace srslte{ logger_file::logger_file() :inited(false) + ,logfile(NULL) ,not_done(true) ,cur_length(0) ,max_length(0) @@ -46,7 +47,9 @@ logger_file::~logger_file() { if(inited) { wait_thread_finish(); flush(); - fclose(logfile); + if (logfile) { + fclose(logfile); + } } } From 5cfffd11e102ef504cfa213d07316d5fd58242d9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 15:51:13 +0100 Subject: [PATCH 171/342] Revert "only reset SDU buffer in RLC AM/UM" This reverts commit 8d852ddfe5e4f6eedb80e247d62b8628f9643c2f. This commit was needed because the order in which objects where destructed on UE exit was such that the byte_buffer was deleted before RLC_AM dtor was called. --- lib/src/upper/rlc_am.cc | 8 ++++++++ lib/src/upper/rlc_um.cc | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index bc24f20bd..f4dced1ec 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -72,6 +72,14 @@ rlc_am::~rlc_am() { // reset RLC and dealloc SDUs stop(); + + if(rx_sdu) { + pool->deallocate(rx_sdu); + } + + if(tx_sdu) { + pool->deallocate(tx_sdu); + } } void rlc_am::init(srslte::log *log_, diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 3fbcbaadf..a365a4501 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -136,11 +136,11 @@ void rlc_um::reset() vr_uh = 0; pdu_lost = false; if(rx_sdu) { - rx_sdu->reset(); + pool->deallocate(rx_sdu); } if(tx_sdu) { - tx_sdu->reset(); + pool->deallocate(tx_sdu); } if(mac_timers) { From 07c704b0ddb7b04da4b34f4defafc4bddb62ec33 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 22 Feb 2018 15:43:40 +0100 Subject: [PATCH 172/342] extend RLC AM stress tester to mimic reestablishment --- lib/test/upper/rlc_am_stress_test.cc | 44 ++++++++++++++++++---------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/lib/test/upper/rlc_am_stress_test.cc b/lib/test/upper/rlc_am_stress_test.cc index c5cf4e877..bdee2248b 100644 --- a/lib/test/upper/rlc_am_stress_test.cc +++ b/lib/test/upper/rlc_am_stress_test.cc @@ -44,6 +44,8 @@ typedef struct { uint32_t test_duration_sec; float error_rate; uint32_t sdu_gen_delay_usec; + uint32_t pdu_tx_delay_usec; + bool reestablish; } stress_test_args_t; void parse_args(stress_test_args_t *args, int argc, char *argv[]) { @@ -58,9 +60,11 @@ void parse_args(stress_test_args_t *args, int argc, char *argv[]) { // Command line or config file options bpo::options_description common("Configuration options"); common.add_options() - ("duration", bpo::value(&args->test_duration_sec)->default_value(10), "Duration (sec)") + ("duration", bpo::value(&args->test_duration_sec)->default_value(10), "Duration (sec)") ("sdu_gen_delay", bpo::value(&args->sdu_gen_delay_usec)->default_value(10), "SDU generation delay (usec)") - ("error_rate", bpo::value(&args->error_rate)->default_value(0.1), "Rate at which RLC PDUs are dropped"); + ("pdu_tx_delay", bpo::value(&args->pdu_tx_delay_usec)->default_value(10), "Delay in MAC for transfering PDU from tx'ing RLC to rx'ing RLC (usec)") + ("error_rate", bpo::value(&args->error_rate)->default_value(0.1), "Rate at which RLC PDUs are dropped") + ("reestablish", bpo::value(&args->reestablish)->default_value(false), "Mimic RLC reestablish during execution"); // these options are allowed on the command line bpo::options_description cmdline_options; @@ -83,14 +87,14 @@ class mac_reader :public thread { public: - mac_reader(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_, uint32_t sdu_gen_delay_usec_) + mac_reader(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_, uint32_t pdu_tx_delay_usec_) { rlc1 = rlc1_; rlc2 = rlc2_; fail_rate = fail_rate_; run_enable = true; running = false; - sdu_gen_delay_usec = sdu_gen_delay_usec_; + pdu_tx_delay_usec = pdu_tx_delay_usec_; } void stop() @@ -125,7 +129,7 @@ private: if(((float)rand()/RAND_MAX > fail_rate) && read>0) { rlc2->write_pdu(1, pdu->msg, opp_size); } - usleep(sdu_gen_delay_usec); + usleep(pdu_tx_delay_usec); } running = false; byte_buffer_pool::get_instance()->deallocate(pdu); @@ -134,7 +138,7 @@ private: rlc_interface_mac *rlc1; rlc_interface_mac *rlc2; float fail_rate; - uint32_t sdu_gen_delay_usec; + uint32_t pdu_tx_delay_usec; bool run_enable; bool running; @@ -144,9 +148,9 @@ class mac_dummy :public srslte::mac_interface_timers { public: - mac_dummy(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_, uint32_t sdu_gen_delay_usec_) - :r1(rlc1_, rlc2_, fail_rate_, sdu_gen_delay_usec_) - ,r2(rlc2_, rlc1_, fail_rate_, sdu_gen_delay_usec_) + mac_dummy(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_, uint32_t pdu_tx_delay) + :r1(rlc1_, rlc2_, fail_rate_, pdu_tx_delay) + ,r2(rlc2_, rlc1_, fail_rate_, pdu_tx_delay) { } @@ -184,12 +188,13 @@ class rlc_am_tester ,public thread { public: - rlc_am_tester(rlc_interface_pdcp *rlc_, std::string name_=""){ + rlc_am_tester(rlc_interface_pdcp *rlc_, std::string name_, uint32_t sdu_gen_delay_usec_){ rlc = rlc_; run_enable = true; running = false; rx_pdus = 0; name = name_; + sdu_gen_delay_usec = sdu_gen_delay_usec_; } void stop() @@ -235,7 +240,7 @@ private: pdu->N_bytes = 1500; pdu->msg[0] = sn++; rlc->write_sdu(1, pdu); - usleep(10); + usleep(sdu_gen_delay_usec); } running = false; } @@ -246,6 +251,8 @@ private: std::string name; + uint32_t sdu_gen_delay_usec; + rlc_interface_pdcp *rlc; }; @@ -261,9 +268,9 @@ void stress_test(stress_test_args_t args) rlc rlc1; rlc rlc2; - rlc_am_tester tester1(&rlc1, "tester1"); - rlc_am_tester tester2(&rlc2, "tester2"); - mac_dummy mac(&rlc1, &rlc2, args.error_rate, args.sdu_gen_delay_usec); + rlc_am_tester tester1(&rlc1, "tester1", args.sdu_gen_delay_usec); + rlc_am_tester tester2(&rlc2, "tester2", args.sdu_gen_delay_usec); + mac_dummy mac(&rlc1, &rlc2, args.error_rate, args.pdu_tx_delay_usec); ue_interface ue; rlc1.init(&tester1, &tester1, &ue, &log1, &mac, 0); @@ -287,7 +294,14 @@ void stress_test(stress_test_args_t args) tester2.start(7); mac.start(); - usleep(args.test_duration_sec * 1e6); + for (uint32_t i = 0; i < args.test_duration_sec; i++) { + // if enabled, mimic reestablishment every second + if (args.reestablish) { + rlc1.reestablish(); + rlc2.reestablish(); + } + usleep(1e6); + } tester1.stop(); tester2.stop(); From c198547728d95fc6b058b8d97e1e738cdfce850c Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 23 Feb 2018 13:23:04 +0100 Subject: [PATCH 173/342] add new RF RX error type and make the UHD driver issue that if anything unexpected happens --- lib/include/srslte/phy/rf/rf.h | 1 + lib/src/phy/rf/rf_uhd_imp.c | 22 ++++++++++++++++++++-- srsue/src/ue.cc | 7 ++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/include/srslte/phy/rf/rf.h b/lib/include/srslte/phy/rf/rf.h index 44bde9943..da1600b66 100644 --- a/lib/include/srslte/phy/rf/rf.h +++ b/lib/include/srslte/phy/rf/rf.h @@ -60,6 +60,7 @@ typedef struct { SRSLTE_RF_ERROR_LATE, SRSLTE_RF_ERROR_UNDERFLOW, SRSLTE_RF_ERROR_OVERFLOW, + SRSLTE_RF_ERROR_RX, SRSLTE_RF_ERROR_OTHER } type; int opt; diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index a1bec2657..0370fa700 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -96,6 +96,19 @@ static void log_underflow(rf_uhd_handler_t *h) { } } +static void log_rx_error(rf_uhd_handler_t *h) { + if (h->uhd_error_handler) { + char error_string[512]; + uhd_usrp_last_error(h->usrp, error_string, 512); + fprintf(stderr, "USRP reported the following error: %s\n", error_string); + + srslte_rf_error_t error; + bzero(&error, sizeof(srslte_rf_error_t)); + error.type = SRSLTE_RF_ERROR_RX; + h->uhd_error_handler(error); + } +} + static void* async_thread(void *h) { rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; uhd_async_metadata_handle md; @@ -740,6 +753,7 @@ int rf_uhd_recv_with_time_multi(void *h, num_rx_samples, md, 1.0, false, &rxd_samples); if (error) { fprintf(stderr, "Error receiving from UHD: %d\n", error); + log_rx_error(handler); return -1; } @@ -762,8 +776,12 @@ int rf_uhd_recv_with_time_multi(void *h, } } } else { - return uhd_rx_streamer_recv(handler->rx_stream, data, - nsamples, md, 0.0, false, &rxd_samples); + uhd_error error = uhd_rx_streamer_recv(handler->rx_stream, data, nsamples, md, 0.0, false, &rxd_samples); + if (error) { + fprintf(stderr, "Error receiving from UHD: %d\n", error); + log_rx_error(handler); + return -1; + } } if (secs && frac_secs) { uhd_rx_metadata_time_spec(handler->rx_md_first, secs, frac_secs); diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 1de1ddbd0..23175fa46 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -304,8 +304,13 @@ void ue::rf_msg(srslte_rf_error_t error) { ue_base *ue = ue_base::get_instance(LTE); ue->handle_rf_msg(error); - if(error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_OVERFLOW) { + if (error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_OVERFLOW) { ue->radio_overflow(); + } else + if (error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_RX) { + ue->stop(); + ue->cleanup(); + exit(-1); } } From c9b459bf8aa087ca7826fb849dacfc2bfd788356 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 5 Mar 2018 09:12:01 +0000 Subject: [PATCH 174/342] Fixing Activate default bearer context uninitialized value. --- srsepc/src/mme/s1ap_nas_transport.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 0cd646136..1c78ed58b 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -1166,6 +1166,7 @@ s1ap_nas_transport::pack_attach_accept(ue_ctx_t *ue_ctx, LIBLTE_S1AP_E_RABTOBESE act_def_eps_bearer_context_req.packet_flow_id_present = false; act_def_eps_bearer_context_req.apn_ambr_present = false; act_def_eps_bearer_context_req.esm_cause_present = false; + act_def_eps_bearer_context_req.connectivity_type_present = false; uint8_t sec_hdr_type =2; ue_ctx->security_ctxt.dl_nas_count++; From 01e56428826d0dc2332c638dfc205aaa235707b0 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 5 Mar 2018 09:51:31 +0000 Subject: [PATCH 175/342] Replying same attach type to the UE as in the attach request. --- srsepc/hdr/mme/s1ap_common.h | 1 + srsepc/src/mme/s1ap_nas_transport.cc | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index 9a7d72ce5..65c16f8c9 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -97,6 +97,7 @@ typedef struct{ LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT ms_network_cap; bool eit; uint8_t procedure_transaction_id; + uint8_t attach_type; } ue_ctx_t; }//namespace #endif diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 1c78ed58b..f8ef987d8 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -311,7 +311,10 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, m_s1ap_log->console("PDN Connectivity Request -- EPS Bearer Identity requested: %d\n", pdn_con_req.eps_bearer_id); m_s1ap_log->console("PDN Connectivity Request -- Procedure Transaction Id: %d\n", pdn_con_req.proc_transaction_id); m_s1ap_log->console("PDN Connectivity Request -- ESM Information Transfer requested: %s\n", pdn_con_req.esm_info_transfer_flag_present ? "true" : "false"); - + + //Save attach request type + ue_ctx.attach_type = attach_req.eps_attach_type; + //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)) { @@ -360,6 +363,9 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, uint8_t eps_bearer_id = pdn_con_req.eps_bearer_id; //TODO: Unused ue_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id; + //Save attach request type + ue_ctx.attach_type = attach_req.eps_attach_type; + //Save whether ESM information transfer is necessary ue_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; //m_s1ap_log->console("EPS Bearer id: %d\n", eps_bearer_id); @@ -412,6 +418,8 @@ s1ap_nas_transport::handle_nas_guti_attach_request(uint32_t enb_ue_s1ap_id, ue_ctx_t *ue_ctx_ptr = m_s1ap->find_ue_ctx(it->second); if(ue_ctx_ptr!=NULL) { + //Save attach request type + ue_ctx_ptr->attach_type = attach_req.eps_attach_type; m_s1ap_log->console("Found UE context. IMSI: %015lu\n",ue_ctx_ptr->imsi); m_mme_gtpc->send_create_session_request(ue_ctx_ptr->imsi, ue_ctx_ptr->mme_ue_s1ap_id); *reply_flag = false; //No reply needed From 0cb1127f934712d244f36e2f0f3f5035860d5117 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 5 Mar 2018 10:05:58 +0000 Subject: [PATCH 176/342] Sending Service reject to UE as a temporary handling of service requests (Thanks to Merlin Chlosta). --- srsepc/hdr/mme/s1ap_nas_transport.h | 1 + srsepc/src/mme/s1ap_nas_transport.cc | 60 +++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index 5a457cec7..e958c8dbc 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -84,6 +84,7 @@ public: bool pack_identity_request(srslte::byte_buffer_t *reply_msg, uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id); bool pack_emm_information(srslte::byte_buffer_t *reply_msg, uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id); + bool pack_service_reject(srslte::byte_buffer_t *reply_msg, uint8_t emm_cause, uint32_t enb_ue_s1ap_id); void log_unhandled_attach_request_ies(const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT *attach_req); void log_unhandled_pdn_con_request_ies(const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT *pdn_con_req); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index f8ef987d8..22d3c63d1 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -121,7 +121,12 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA m_s1ap_log->info("Received Service Request \n"); m_s1ap_log->console("Received Service Request \n"); liblte_mme_unpack_service_request_msg((LIBLTE_BYTE_MSG_STRUCT*) nas_msg, &service_req); - return false; + + m_s1ap_log->info("Service Request not implemented. Sending Service Reject."); + m_s1ap_log->console("Service Request not implemented. Sending Service Reject."); + /* Force UE to re-attach */ + pack_service_reject(reply_buffer, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED, enb_ue_s1ap_id); + *reply_flag = true; } m_pool->deallocate(nas_msg); @@ -1322,6 +1327,59 @@ s1ap_nas_transport::pack_emm_information(srslte::byte_buffer_t *reply_msg, uint3 return true; } +bool +s1ap_nas_transport::pack_service_reject(srslte::byte_buffer_t *reply_msg, uint8_t emm_cause, uint32_t enb_ue_s1ap_id) +{ + srslte::byte_buffer_t *nas_buffer = m_pool->allocate(); + + //Setup initiating message + LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu; + bzero(&tx_pdu, sizeof(LIBLTE_S1AP_S1AP_PDU_STRUCT)); + + tx_pdu.ext = false; + tx_pdu.choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE; + + LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *init = &tx_pdu.choice.initiatingMessage; + init->procedureCode = LIBLTE_S1AP_PROC_ID_DOWNLINKNASTRANSPORT; + init->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DOWNLINKNASTRANSPORT; + + //Setup Dw NAS structure + LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT *dw_nas = &init->choice.DownlinkNASTransport; + dw_nas->ext=false; + dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = m_s1ap->get_next_mme_ue_s1ap_id(); + dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = enb_ue_s1ap_id; + dw_nas->HandoverRestrictionList_present=false; + dw_nas->SubscriberProfileIDforRFP_present=false; + LIBLTE_MME_SERVICE_REJECT_MSG_STRUCT service_rej; + service_rej.t3442_present = true; + service_rej.t3442.unit = LIBLTE_MME_GPRS_TIMER_DEACTIVATED; + service_rej.t3442.value = 0; + service_rej.t3446_present = true; + service_rej.t3446 = 0; + service_rej.emm_cause = emm_cause; + + LIBLTE_ERROR_ENUM err = liblte_mme_pack_service_reject_msg(&service_rej, LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS, 0, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); + if(err != LIBLTE_SUCCESS) + { + m_s1ap_log->error("Error packing Service Reject\n"); + m_s1ap_log->console("Error packing Service Reject\n"); + return false; + } + + //Copy NAS PDU to Downlink NAS Trasport message buffer + memcpy(dw_nas->NAS_PDU.buffer, nas_buffer->msg, nas_buffer->N_bytes); + dw_nas->NAS_PDU.n_octets = nas_buffer->N_bytes; + + //Pack Downlink NAS Transport Message + err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_msg); + if(err != LIBLTE_SUCCESS) + { + m_s1ap_log->error("Error packing Dw NAS Transport: Service Reject\n"); + m_s1ap_log->console("Error packing Downlink NAS Transport: Service Reject\n"); + return false; + } + return true; +} /*Helper functions*/ void s1ap_nas_transport::log_unhandled_attach_request_ies(const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT *attach_req) From 067d76a5c8cc5e4ef0619d28b96e28777c20f1b2 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 5 Mar 2018 11:22:02 +0100 Subject: [PATCH 177/342] enable buffer pool log --- lib/include/srslte/common/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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__)) From 3efc197f3a7f2b48f83ae91836a721efbe1b48dd Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 5 Mar 2018 10:50:51 +0000 Subject: [PATCH 178/342] Actually changing the attach type. --- srsepc/src/mme/s1ap_nas_transport.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 22d3c63d1..5f791caa5 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -293,6 +293,10 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, m_s1ap_log->console("Attach request -- IMSI: %015lu\n", ue_ctx.imsi); m_s1ap_log->info("Attach request -- IMSI: %015lu\n", ue_ctx.imsi); + + m_s1ap_log->console("Attach request -- Attach type: %d\n", attach_req.eps_attach_type); + m_s1ap_log->info("Attach request -- Attach type: %d\n", attach_req.eps_attach_type); + m_s1ap_log->console("Attach request -- eNB-UE S1AP Id: %d, MME-UE S1AP Id: %d\n", ue_ctx.enb_ue_s1ap_id, ue_ctx.mme_ue_s1ap_id); m_s1ap_log->console("Attach Request -- UE Network Capabilities EEA: %d%d%d%d%d%d%d%d\n", attach_req.ue_network_cap.eea[0], @@ -1106,7 +1110,7 @@ s1ap_nas_transport::pack_attach_accept(ue_ctx_t *ue_ctx, LIBLTE_S1AP_E_RABTOBESE } //Attach accept - attach_accept.eps_attach_result = LIBLTE_MME_EPS_ATTACH_RESULT_EPS_ONLY; + attach_accept.eps_attach_result = ue_ctx->attach_type; //Mandatory //FIXME: Set t3412 from config attach_accept.t3412.unit = LIBLTE_MME_GPRS_TIMER_UNIT_1_MINUTE; // GPRS 1 minute unit From 90553e830d4211edbd2fdb997ecee718ec00ae6f Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 13:07:24 +0100 Subject: [PATCH 179/342] Fixed cell search for non-home PLMN --- lib/include/srslte/interfaces/ue_interfaces.h | 1 - lib/src/phy/ue/ue_sync.c | 7 +- srsue/hdr/phy/phch_recv.h | 8 +- srsue/hdr/phy/phy.h | 1 - srsue/src/phy/phch_recv.cc | 87 +++++++------------ srsue/src/phy/phy.cc | 5 -- srsue/src/upper/nas.cc | 17 ++-- srsue/src/upper/rrc.cc | 39 +++++---- 8 files changed, 76 insertions(+), 89 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 52d11416c..923111371 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -580,7 +580,6 @@ public: /* Cell search and selection procedures */ virtual void cell_search_start() = 0; - virtual void cell_search_stop() = 0; virtual void cell_search_next() = 0; virtual void cell_select(uint32_t earfcn, srslte_cell_t cell) = 0; virtual bool cell_handover(srslte_cell_t cell) = 0; diff --git a/lib/src/phy/ue/ue_sync.c b/lib/src/phy/ue/ue_sync.c index d99bff89a..b66cf5b53 100644 --- a/lib/src/phy/ue/ue_sync.c +++ b/lib/src/phy/ue/ue_sync.c @@ -755,7 +755,9 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE if (q->do_agc) { srslte_agc_process(&q->agc, input_buffer[0], q->sf_len); } - + + INFO("SYNC FIND: sf_idx=%d, ret=%d, next_state=%d\n", q->sf_idx, ret, q->state); + break; case SF_TRACK: @@ -817,6 +819,9 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE q->frame_total_cnt++; } + + INFO("SYNC TRACK: sf_idx=%d, ret=%d, next_state=%d\n", q->sf_idx, ret, q->state); + break; } } diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index b5848a6b3..861d58229 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -61,7 +61,6 @@ public: void reset_sync(); void cell_search_start(); - void cell_search_stop(); void cell_search_next(bool reset = false); void cell_select(uint32_t earfcn, srslte_cell_t cell); bool cell_handover(srslte_cell_t cell); @@ -299,14 +298,16 @@ private: const static uint32_t NOF_IN_SYNC_SF = 100; // State for primary cell - enum { + typedef enum { IDLE = 0, CELL_SEARCH, CELL_SELECT, CELL_RESELECT, CELL_MEASURE, CELL_CAMP, - } phy_state; + } phy_state_t; + + phy_state_t phy_state, prev_state; bool is_in_idle; @@ -330,7 +331,6 @@ private: float ul_dl_factor; uint32_t current_earfcn; int cur_earfcn_index; - bool cell_search_in_progress; float dl_freq; float ul_freq; diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index 9270973c0..0894a98fb 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -85,7 +85,6 @@ public: void sync_reset(); void configure_ul_params(bool pregen_disabled = false); void cell_search_start(); - void cell_search_stop(); void cell_search_next(); void cell_select(uint32_t earfcn, srslte_cell_t phy_cell); bool cell_handover(srslte_cell_t cell); diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index a6f1a5d84..ad76537e0 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -132,7 +132,6 @@ void phch_recv::reset() next_offset = 0; cell_is_set = false; srate_mode = SRATE_NONE; - cell_search_in_progress = false; current_earfcn = 0; sfn_p.reset(); measure_p.reset(); @@ -262,17 +261,17 @@ void phch_recv::reset_sync() { search_p.reset(); measure_p.reset(); srslte_ue_sync_reset(&ue_sync); - + Info("----- PHY RESET----\n"); phy_state = CELL_SELECT; } void phch_recv::cell_search_inc() { + Info("cell_search_inc, cur_idx=%d, size=%d\n", cur_earfcn_index, earfcn.size()); cur_earfcn_index++; if (cur_earfcn_index >= 0) { if (cur_earfcn_index >= (int) earfcn.size()) { cur_earfcn_index = 0; - cell_search_in_progress = false; phy_state = IDLE; rrc->earfcn_end(); } else { @@ -281,20 +280,16 @@ void phch_recv::cell_search_inc() current_earfcn = earfcn[cur_earfcn_index]; set_frequency(); } + phy_state = CELL_SEARCH; } } } void phch_recv::cell_search_next(bool reset) { - if (cell_search_in_progress || reset) { - cell_search_in_progress = false; - if (reset) { - cur_earfcn_index = -1; - } - cell_search_inc(); - phy_state = CELL_SEARCH; - cell_search_in_progress = true; + if (reset) { + cur_earfcn_index = -1; } + cell_search_inc(); } void phch_recv::cell_search_start() { @@ -311,11 +306,6 @@ void phch_recv::cell_search_start() { } } -void phch_recv::cell_search_stop() { - Info("SYNC: Stopping Cell Search procedure...\n"); - cell_search_in_progress = false; -} - bool phch_recv::cell_handover(srslte_cell_t cell) { int cnt = 0; @@ -369,19 +359,18 @@ void phch_recv::cell_reselect() uint32_t earfcn = new_earfcn; srslte_cell_t cell = new_cell; + Info("Reset from cell_reselect\n"); + reset_sync(); + // If we are already in the new cell, just resynchronize if (earfcn == current_earfcn && this->cell.id == cell.id) { - log_h->info("Cell Select: Already in cell EARFCN=%d\n", earfcn); - cell_search_in_progress = false; + log_h->info("Cell Select: Already in cell EARFCN=%d, PCI=%d\n", earfcn, cell.id); if (srate_mode != SRATE_CAMP) { set_sampling_rate(); + log_h->info("Cell Select: Setting Camping sampling rate\n"); } - phy_state = CELL_SELECT; } else { - /* If we are going to a new cell, configure it */ - cell_search_in_progress = false; - if (earfcn != current_earfcn) { if (set_frequency()) { log_h->error("Cell Select: Configuring cell in EARFCN=%d, PCI=%d\n", earfcn, cell.id); @@ -394,7 +383,6 @@ void phch_recv::cell_reselect() if (set_cell()) { log_h->info("Cell Select: Synchronizing on cell...\n"); - phy_state = CELL_SELECT; } } } @@ -533,33 +521,29 @@ void phch_recv::run_thread() sf_idx = tti%10; + prev_state = phy_state; + switch (phy_state) { case CELL_SEARCH: - if (cell_search_in_progress) + switch(search_p.run(&cell)) { - switch(search_p.run(&cell)) - { - case search::CELL_FOUND: - if (!srslte_cell_isvalid(&cell)) { - Error("SYNC: Detected invalid cell\n"); - phy_state = IDLE; - break; - } - if (set_cell()) { - set_sampling_rate(); - phy_state = CELL_SELECT; - } - break; - case search::CELL_NOT_FOUND: - if (cell_search_in_progress) { - cell_search_inc(); - } + case search::CELL_FOUND: + if (!srslte_cell_isvalid(&cell)) { + Error("SYNC: Detected invalid cell\n"); phy_state = IDLE; break; - default: - radio_error(); - break; } + if (set_cell()) { + set_sampling_rate(); + phy_state = CELL_SELECT; + } + break; + case search::CELL_NOT_FOUND: + cell_search_inc(); + break; + default: + radio_error(); + break; } break; case CELL_RESELECT: @@ -569,7 +553,7 @@ void phch_recv::run_thread() switch (sfn_p.run_subframe(&cell, &tti)) { case sfn_sync::SFN_FOUND: - if (!cell_search_in_progress) { + if (prev_state == CELL_SEARCH) { log_h->info("Sync OK. Camping on cell PCI=%d...\n", cell.id); phy_state = CELL_CAMP; rrc->cell_camping(earfcn[cur_earfcn_index], cell); @@ -580,13 +564,8 @@ void phch_recv::run_thread() } break; case sfn_sync::TIMEOUT: - if (cell_search_in_progress) { - log_h->warning("SYNC: Timeout while synchronizing SFN. Going back to cell search\n"); - phy_state = CELL_SEARCH; - } else { - log_h->warning("SYNC: Timeout while synchronizing SFN. Reselecting cell\n"); - phy_state = CELL_SELECT; - } + log_h->warning("SYNC: Timeout while synchronizing SFN. Going back to cell search\n"); + phy_state = CELL_SEARCH; break; case sfn_sync::IDLE: break; @@ -610,7 +589,6 @@ void phch_recv::run_thread() log_h->info("SYNC: Measured OK. Camping on cell PCI=%d...\n", cell.id); phy_state = CELL_CAMP; - cell_search_in_progress = false; rrc->cell_camping(earfcn[cur_earfcn_index], cell, measure_p.rsrp()); break; case measure::IDLE: @@ -833,6 +811,7 @@ phch_recv::search::ret_code phch_recv::search::run(srslte_cell_t *cell) if (p->srate_mode != SRATE_FIND) { p->srate_mode = SRATE_FIND; p->radio_h->set_rx_srate(1.92e6); + Info("SYNC: Setting Cell Search sampling rate\n"); } /* Find a cell in the given N_id_2 or go through the 3 of them to find the strongest */ @@ -992,7 +971,7 @@ phch_recv::sfn_sync::ret_code phch_recv::sfn_sync::run_subframe(srslte_cell_t *c } } } else { - Debug("SYNC: PSS/SSS not found...\n"); + Info("SYNC: PSS/SSS not found...\n"); } cnt++; diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index a2d517a02..e4b618158 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -256,11 +256,6 @@ void phy::cell_search_start() sf_recv.cell_search_start(); } -void phy::cell_search_stop() -{ - sf_recv.cell_search_stop(); -} - void phy::cell_search_next() { sf_recv.cell_search_next(); diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 7f5683867..8a05595c7 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -161,14 +161,15 @@ void nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_ // RRC indicates that the UE has gone through all EARFCN and finished PLMN selection void nas::plmn_search_end() { if (known_plmns.size() > 0) { - nas_log->info("Could not find Home PLMN Id=%s, trying to connect to PLMN Id=%s\n", - plmn_id_to_string(home_plmn).c_str(), - plmn_id_to_string(known_plmns[0]).c_str()); - - nas_log->console("Could not find Home PLMN Id=%s, trying to connect to PLMN Id=%s\n", - plmn_id_to_string(home_plmn).c_str(), - plmn_id_to_string(known_plmns[0]).c_str()); - + if (home_plmn.mcc != known_plmns[0].mcc && home_plmn.mnc != known_plmns[0].mnc) { + nas_log->info("Could not find Home PLMN Id=%s, trying to connect to PLMN Id=%s\n", + plmn_id_to_string(home_plmn).c_str(), + plmn_id_to_string(known_plmns[0]).c_str()); + + nas_log->console("Could not find Home PLMN Id=%s, trying to connect to PLMN Id=%s\n", + plmn_id_to_string(home_plmn).c_str(), + plmn_id_to_string(known_plmns[0]).c_str()); + } rrc->plmn_select(known_plmns[0]); } else { nas_log->info("Finished searching PLMN in current EARFCN set but no networks were found.\n"); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 1aecb273b..cdd19f22c 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -212,10 +212,8 @@ void rrc::run_thread() { plmn_select_timeout++; if (plmn_select_timeout >= RRC_PLMN_SELECT_TIMEOUT) { rrc_log->info("RRC PLMN Search: timeout expired\n"); - phy->cell_search_stop(); - sleep(1); - rrc_log->console("\nRRC PLMN Search: timeout expired. Searching again\n"); - + rrc_log->console("\nRRC PLMN Search: timeout expired.\n"); + state = RRC_STATE_IDLE; } break; case RRC_STATE_CELL_SELECTING: @@ -236,14 +234,13 @@ void rrc::run_thread() { } } // Don't time out during reestablishment (T311 running) - if (!mac_timers->timer_get(t311)->is_running()) { + if (!mac_timers->timer_get(t311)->is_running() || !phy->sync_status()) { select_cell_timeout++; if (select_cell_timeout >= RRC_SELECT_CELL_TIMEOUT) { rrc_log->info("RRC Cell Selecting: timeout expired. Starting Cell Search...\n"); - plmn_select_timeout = 0; select_cell_timeout = 0; + state = RRC_STATE_PLMN_START; serving_cell->in_sync = false; - phy->cell_search_start(); } } break; @@ -457,17 +454,30 @@ void rrc::plmn_select_rrc(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { if (state == RRC_STATE_IDLE || state == RRC_STATE_CONNECTED || state == RRC_STATE_PLMN_SELECTION) { if (phy->sync_status() && selected_plmn_id.mcc == plmn_id.mcc && selected_plmn_id.mnc == plmn_id.mnc) { rrc_log->info("Already camping on selected PLMN, connecting...\n"); - state = RRC_STATE_CELL_SELECTING; - select_cell_timeout = 0; } else { - rrc_log->info("PLMN Id=%s selected\n", plmn_id_to_string(plmn_id).c_str()); - // Sort cells according to RSRP - selected_plmn_id = plmn_id; - select_cell_timeout = 0; - state = RRC_STATE_CELL_SELECTING; + if (serving_cell->plmn_equals(selected_plmn_id)) { + phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); + } else { + bool found = false; + for (uint32_t i=0;iplmn_equals(selected_plmn_id)) { + rrc_log->info("PLMN Id=%s selected, PCI=%d\n", plmn_id_to_string(plmn_id).c_str(), neighbour_cells[i]->get_pci()); + phy->cell_select(neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->phy_cell); + found = true; + } + } + if (!found) { + rrc_log->warning("Could not find any cell for the selected PLMN\n"); + state = RRC_STATE_IDLE; + return; + } + } } + + state = RRC_STATE_CELL_SELECTING; + select_cell_timeout = 0; } else { rrc_log->warning("Requested PLMN select in incorrect state %s\n", rrc_state_text[state]); } @@ -988,7 +998,6 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause, break; default: rrc_log->info("Unsupported integrity algorithm during reestablishment\n"); - return; } // Prepare ConnectionRestalishmentRequest packet From 8591049e928da086cfb599b08799a1d46f992c18 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 14:33:51 +0100 Subject: [PATCH 180/342] Added mutex to ul/dl harq reset --- lib/src/common/pdu_queue.cc | 12 ++++++++---- srsue/hdr/mac/dl_harq.h | 16 +++++++++++++++- srsue/hdr/mac/ul_harq.h | 11 ++++++++++- srsue/src/upper/rrc.cc | 2 ++ 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/lib/src/common/pdu_queue.cc b/lib/src/common/pdu_queue.cc index 3a116e641..061433033 100644 --- a/lib/src/common/pdu_queue.cc +++ b/lib/src/common/pdu_queue.cc @@ -76,10 +76,14 @@ void pdu_queue::deallocate(uint8_t* pdu) */ void pdu_queue::push(uint8_t *ptr, uint32_t len, uint32_t tstamp) { - pdu_t *pdu = (pdu_t*) ptr; - pdu->len = len; - pdu->tstamp = tstamp; - pdu_q.push(pdu); + if (ptr) { + pdu_t *pdu = (pdu_t*) ptr; + pdu->len = len; + pdu->tstamp = tstamp; + pdu_q.push(pdu); + } else { + log_h->warning("Error pushing pdu: ptr is empty\n"); + } } bool pdu_queue::process_pdus() diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index 261fb0d41..982a6eac6 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -196,6 +196,8 @@ private: is_initiated = false; ack = false; bzero(&cur_grant, sizeof(Tgrant)); + + pthread_mutex_init(&mutex, NULL); } ~dl_tb_process() { @@ -220,16 +222,23 @@ private: } void reset(void) { + pthread_mutex_lock(&mutex); is_first_tb = true; ack = false; - payload_buffer_ptr = NULL; + if (payload_buffer_ptr) { + harq_entity->demux_unit->deallocate(payload_buffer_ptr); + } bzero(&cur_grant, sizeof(Tgrant)); if (is_initiated) { srslte_softbuffer_rx_reset(&softbuffer); } + pthread_mutex_unlock(&mutex); } void new_grant_dl(Tgrant grant, Taction *action) { + + pthread_mutex_lock(&mutex); + // Compute RV for BCCH when not specified in PDCCH format if (pid == HARQ_BCCH_PID && grant.rv[tid] == -1) { uint32_t k; @@ -271,6 +280,7 @@ private: if (!action->payload_ptr[tid]) { action->decode_enabled[tid] = false; Error("Can't get a buffer for TBS=%d\n", cur_grant.n_bytes[tid]); + pthread_mutex_unlock(&mutex); return; } action->decode_enabled[tid]= true; @@ -299,6 +309,8 @@ private: Debug("Generating ACK\n"); } } + + pthread_mutex_unlock(&mutex); } void tb_decoded(bool ack_) { @@ -364,6 +376,8 @@ private: return is_new_transmission; } + pthread_mutex_t mutex; + bool is_initiated; dl_harq_entity *harq_entity; srslte::log *log_h; diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index 5c44a222e..4ab4756b9 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -159,6 +159,8 @@ private: tti_last_tx = 0; payload_buffer = NULL; bzero(&cur_grant, sizeof(Tgrant)); + + pthread_mutex_init(&mutex, NULL); } ~ul_harq_process() @@ -193,17 +195,21 @@ private: void reset() { + pthread_mutex_lock(&mutex); current_tx_nb = 0; current_irv = 0; tti_last_tx = 0; is_grant_configured = false; bzero(&cur_grant, sizeof(Tgrant)); + pthread_mutex_unlock(&mutex); } void reset_ndi() { cur_grant.ndi[0] = false; } void run_tti(uint32_t tti_tx, Tgrant *grant, bool *ack, Taction* action) { + pthread_mutex_lock(&mutex); + if (ack) { if (grant) { if (grant->ndi[0] == get_ndi() && grant->phy_grant.ul.mcs.tbs != 0) { @@ -276,6 +282,8 @@ private: } harq_entity->pcap->write_ul_crnti(pdu_ptr, grant->n_bytes[0], grant->rnti, get_nof_retx(), tti_tx); } + + pthread_mutex_unlock(&mutex); } uint32_t get_rv() @@ -304,7 +312,8 @@ private: bool is_msg3; bool is_initiated; uint32_t tti_last_tx; - + + pthread_mutex_t mutex; const static int payload_buffer_len = 128*1024; uint8_t *payload_buffer; diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 8ffdc1868..f2373ce2c 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -768,6 +768,8 @@ void rrc::earfcn_end() { // If searching for PLMN, indicate NAS we scanned all frequencies if (state == RRC_STATE_PLMN_SELECTION) { nas->plmn_search_end(); + } else if (state == RRC_STATE_CONNECTED) { + leave_connected(); } } From f53cb11e82c3cc4a0818c05226d54083c3da0a08 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 14:54:01 +0100 Subject: [PATCH 181/342] Remove mutex from ul_harq --- srsue/hdr/mac/ul_harq.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index 4ab4756b9..ee9bc6279 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -159,8 +159,6 @@ private: tti_last_tx = 0; payload_buffer = NULL; bzero(&cur_grant, sizeof(Tgrant)); - - pthread_mutex_init(&mutex, NULL); } ~ul_harq_process() @@ -195,21 +193,17 @@ private: void reset() { - pthread_mutex_lock(&mutex); current_tx_nb = 0; current_irv = 0; tti_last_tx = 0; is_grant_configured = false; bzero(&cur_grant, sizeof(Tgrant)); - pthread_mutex_unlock(&mutex); } void reset_ndi() { cur_grant.ndi[0] = false; } void run_tti(uint32_t tti_tx, Tgrant *grant, bool *ack, Taction* action) { - pthread_mutex_lock(&mutex); - if (ack) { if (grant) { if (grant->ndi[0] == get_ndi() && grant->phy_grant.ul.mcs.tbs != 0) { @@ -282,8 +276,6 @@ private: } harq_entity->pcap->write_ul_crnti(pdu_ptr, grant->n_bytes[0], grant->rnti, get_nof_retx(), tti_tx); } - - pthread_mutex_unlock(&mutex); } uint32_t get_rv() @@ -313,7 +305,6 @@ private: bool is_initiated; uint32_t tti_last_tx; - pthread_mutex_t mutex; const static int payload_buffer_len = 128*1024; uint8_t *payload_buffer; From 23f308666976d347b9792cd77b30b0bd486b2778 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 15:13:24 +0100 Subject: [PATCH 182/342] Deallocate properly on dl_harq --- srsue/hdr/mac/dl_harq.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index 982a6eac6..562008d61 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -227,6 +227,7 @@ private: ack = false; if (payload_buffer_ptr) { harq_entity->demux_unit->deallocate(payload_buffer_ptr); + payload_buffer_ptr = NULL; } bzero(&cur_grant, sizeof(Tgrant)); if (is_initiated) { @@ -314,6 +315,7 @@ private: } void tb_decoded(bool ack_) { + pthread_mutex_lock(&mutex); ack = ack_; if (ack) { if (pid == HARQ_BCCH_PID) { @@ -344,11 +346,15 @@ private: harq_entity->demux_unit->deallocate(payload_buffer_ptr); } + payload_buffer_ptr = NULL; + Info("DL %d (TB %d): %s tbs=%d, rv=%d, ack=%s, ndi=%d (%d), tti=%d (%d)\n", pid, tid, is_new_transmission ? "newTX" : "reTX ", cur_grant.n_bytes[tid], cur_grant.rv[tid], ack ? "OK" : "KO", cur_grant.ndi[tid], cur_grant.last_ndi[tid], cur_grant.tti, cur_grant.last_tti); + pthread_mutex_unlock(&mutex); + if (ack && pid == HARQ_BCCH_PID) { reset(); } From b8b39d6d1bd8f5fd4dbfde4a36efd4fd5ff575cf Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 15:16:21 +0100 Subject: [PATCH 183/342] NULL payload buffer in dl_harq in the constructor --- srsue/hdr/mac/dl_harq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index 562008d61..9d7d8f48e 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -196,7 +196,7 @@ private: is_initiated = false; ack = false; bzero(&cur_grant, sizeof(Tgrant)); - + payload_buffer_ptr = NULL; pthread_mutex_init(&mutex, NULL); } From 09594d805871b539e540d4d1c219f040beffc4c6 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 16:18:40 +0100 Subject: [PATCH 184/342] Restart RX stream on srate change --- lib/src/radio/radio.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index 7008790a3..fc21b73be 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -301,7 +301,9 @@ void radio::set_master_clock_rate(double rate) void radio::set_rx_srate(double srate) { + srslte_rf_stop_rx_stream(&rf_device); srslte_rf_set_rx_srate(&rf_device, srate); + srslte_rf_start_rx_stream(&rf_device, false); } void radio::set_tx_freq(double freq) From 76ed6fd8d809bd9aa6dc197080d27bbedcc35ba7 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 16:19:26 +0100 Subject: [PATCH 185/342] Check cell state before infra_freq.meas --- srsue/src/phy/phch_recv.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index ddb0c6a38..b05a88205 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -553,7 +553,7 @@ void phch_recv::run_thread() switch (sfn_p.run_subframe(&cell, &tti)) { case sfn_sync::SFN_FOUND: - if (prev_state == CELL_SEARCH) { + if (prev_state != CELL_SEARCH) { log_h->info("Sync OK. Camping on cell PCI=%d...\n", cell.id); phy_state = CELL_CAMP; rrc->cell_camping(earfcn[cur_earfcn_index], cell); @@ -662,7 +662,9 @@ void phch_recv::run_thread() if ((tti%5) == 0 && worker_com->args->sic_pss_enabled) { srslte_pss_sic(&ue_sync.strack.pss, &buffer[0][SRSLTE_SF_LEN_PRB(cell.nof_prb)/2-ue_sync.strack.fft_size]); } - intra_freq_meas.write(tti, buffer[0], SRSLTE_SF_LEN_PRB(cell.nof_prb)); + if (srslte_cell_isvalid(&cell)) { + intra_freq_meas.write(tti, buffer[0], SRSLTE_SF_LEN_PRB(cell.nof_prb)); + } break; case 0: Warning("SYNC: Out-of-sync detected in PSS/SSS\n"); From 8b1ba55eaf7ecec4ab2c200a98c64ea0a04c5e3d Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 16:20:06 +0100 Subject: [PATCH 186/342] Check payload length before demux --- srsue/src/mac/demux.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/srsue/src/mac/demux.cc b/srsue/src/mac/demux.cc index 56446bda9..99f7c036c 100644 --- a/srsue/src/mac/demux.cc +++ b/srsue/src/mac/demux.cc @@ -165,7 +165,14 @@ void demux::process_sch_pdu(srslte::sch_pdu *pdu_msg) // Route logical channel if (route_pdu) { Info("Delivering PDU for lcid=%d, %d bytes\n", pdu_msg->get()->get_sdu_lcid(), pdu_msg->get()->get_payload_size()); - rlc->write_pdu(pdu_msg->get()->get_sdu_lcid(), pdu_msg->get()->get_sdu_ptr(), pdu_msg->get()->get_payload_size()); + if (pdu_msg->get()->get_payload_size() < MAX_PDU_LEN) { + rlc->write_pdu(pdu_msg->get()->get_sdu_lcid(), pdu_msg->get()->get_sdu_ptr(), pdu_msg->get()->get_payload_size()); + } else { + char tmp[1024]; + srslte_vec_sprint_hex(tmp, pdu_msg->get()->get_sdu_ptr(), 32); + Error("PDU size %d exceeds maximum PDU buffer size, lcid=%d, hex=[%s]\n", + pdu_msg->get()->get_payload_size(), pdu_msg->get()->get_sdu_lcid(), tmp); + } } } else { // Process MAC Control Element From defe16767299d26086ef56b6c0477a460ad135a6 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 16:20:45 +0100 Subject: [PATCH 187/342] Do not lock on set_crnti worker --- srsue/src/phy/phch_worker.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 3075b0b30..de73764f4 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -199,11 +199,9 @@ void phch_worker::set_sample_offset(float sample_offset) void phch_worker::set_crnti(uint16_t rnti) { - pthread_mutex_lock(&mutex); srslte_ue_dl_set_rnti(&ue_dl, rnti); srslte_ue_ul_set_rnti(&ue_ul, rnti); rnti_is_set = true; - pthread_mutex_unlock(&mutex); } float phch_worker::get_ref_cfo() From dcdb2d64496844761c674af8574c48c9fc1468f5 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 16:26:51 +0100 Subject: [PATCH 188/342] Make sure request connection when NAS attaching --- srsue/src/upper/rrc.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index f2373ce2c..11cb432fa 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -187,6 +187,7 @@ void rrc::run_thread() { sleep(1); rrc_log->info("RRC IDLE: NAS is attaching and camping on cell, reselecting...\n"); plmn_select_rrc(selected_plmn_id); + connection_requested = true; } // If not camping on a cell } else { From 5f0bd0e74bd1bdafbf8e831a137d84f3150f37c8 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 17:18:51 +0100 Subject: [PATCH 189/342] Add mutex to libfftw mkplan/destroyplan functions --- lib/src/phy/dft/dft_fftw.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/lib/src/phy/dft/dft_fftw.c b/lib/src/phy/dft/dft_fftw.c index ede6ce69b..d9318fa0d 100644 --- a/lib/src/phy/dft/dft_fftw.c +++ b/lib/src/phy/dft/dft_fftw.c @@ -45,6 +45,7 @@ #define FFTW_TYPE 0 #endif +pthread_mutex_t fft_mutex = PTHREAD_MUTEX_INITIALIZER; void srslte_dft_load() { #ifdef FFTW_WISDOM_FILE @@ -101,10 +102,15 @@ int srslte_dft_replan_guru_c(srslte_dft_plan_t *plan, const int new_dft_points, const fftwf_iodim iodim = {new_dft_points, istride, ostride}; const fftwf_iodim howmany_dims = {how_many, idist, odist}; + pthread_mutex_lock(&fft_mutex); + /* Destroy current plan */ fftwf_destroy_plan(plan->p); plan->p = fftwf_plan_guru_dft(1, &iodim, 1, &howmany_dims, in_buffer, out_buffer, sign, FFTW_TYPE); + + pthread_mutex_unlock(&fft_mutex); + if (!plan->p) { return -1; } @@ -116,11 +122,15 @@ int srslte_dft_replan_guru_c(srslte_dft_plan_t *plan, const int new_dft_points, int srslte_dft_replan_c(srslte_dft_plan_t *plan, const int new_dft_points) { int sign = (plan->dir == SRSLTE_DFT_FORWARD) ? FFTW_FORWARD : FFTW_BACKWARD; + + pthread_mutex_lock(&fft_mutex); if (plan->p) { fftwf_destroy_plan(plan->p); plan->p = NULL; } plan->p = fftwf_plan_dft_1d(new_dft_points, plan->in, plan->out, sign, FFTW_TYPE); + pthread_mutex_unlock(&fft_mutex); + if (!plan->p) { return -1; } @@ -136,10 +146,14 @@ int srslte_dft_plan_guru_c(srslte_dft_plan_t *plan, const int dft_points, srslte const fftwf_iodim iodim = {dft_points, istride, ostride}; const fftwf_iodim howmany_dims = {how_many, idist, odist}; + pthread_mutex_lock(&fft_mutex); + plan->p = fftwf_plan_guru_dft(1, &iodim, 1, &howmany_dims, in_buffer, out_buffer, sign, FFTW_TYPE); if (!plan->p) { return -1; } + pthread_mutex_unlock(&fft_mutex); + plan->size = dft_points; plan->init_size = plan->size; plan->mode = SRSLTE_DFT_COMPLEX; @@ -156,8 +170,14 @@ int srslte_dft_plan_guru_c(srslte_dft_plan_t *plan, const int dft_points, srslte int srslte_dft_plan_c(srslte_dft_plan_t *plan, const int dft_points, srslte_dft_dir_t dir) { allocate(plan,sizeof(fftwf_complex),sizeof(fftwf_complex), dft_points); + + pthread_mutex_lock(&fft_mutex); + int sign = (dir == SRSLTE_DFT_FORWARD) ? FFTW_FORWARD : FFTW_BACKWARD; plan->p = fftwf_plan_dft_1d(dft_points, plan->in, plan->out, sign, FFTW_TYPE); + + pthread_mutex_unlock(&fft_mutex); + if (!plan->p) { return -1; } @@ -177,11 +197,15 @@ int srslte_dft_plan_c(srslte_dft_plan_t *plan, const int dft_points, srslte_dft_ int srslte_dft_replan_r(srslte_dft_plan_t *plan, const int new_dft_points) { int sign = (plan->dir == SRSLTE_DFT_FORWARD) ? FFTW_R2HC : FFTW_HC2R; + + pthread_mutex_lock(&fft_mutex); if (plan->p) { fftwf_destroy_plan(plan->p); plan->p = NULL; } plan->p = fftwf_plan_r2r_1d(new_dft_points, plan->in, plan->out, sign, FFTW_TYPE); + pthread_mutex_unlock(&fft_mutex); + if (!plan->p) { return -1; } @@ -192,7 +216,11 @@ int srslte_dft_replan_r(srslte_dft_plan_t *plan, const int new_dft_points) { int srslte_dft_plan_r(srslte_dft_plan_t *plan, const int dft_points, srslte_dft_dir_t dir) { allocate(plan,sizeof(float),sizeof(float), dft_points); int sign = (dir == SRSLTE_DFT_FORWARD) ? FFTW_R2HC : FFTW_HC2R; + + pthread_mutex_lock(&fft_mutex); plan->p = fftwf_plan_r2r_1d(dft_points, plan->in, plan->out, sign, FFTW_TYPE); + pthread_mutex_unlock(&fft_mutex); + if (!plan->p) { return -1; } @@ -311,11 +339,15 @@ void srslte_dft_run_r(srslte_dft_plan_t *plan, const float *in, float *out) { void srslte_dft_plan_free(srslte_dft_plan_t *plan) { if (!plan) return; if (!plan->size) return; + + pthread_mutex_lock(&fft_mutex); if (!plan->is_guru) { if (plan->in) fftwf_free(plan->in); if (plan->out) fftwf_free(plan->out); } if (plan->p) fftwf_destroy_plan(plan->p); + pthread_mutex_unlock(&fft_mutex); + bzero(plan, sizeof(srslte_dft_plan_t)); } From 154623ed63f743227714a0e6a09b6592269e36f2 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 17:39:34 +0100 Subject: [PATCH 190/342] Decrease the in-sync SNR threshold --- 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 de73764f4..3a1dcbc98 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -410,7 +410,7 @@ void phch_worker::work_imp() update_measurements(); if (chest_ok) { - if (phy->avg_rsrp_dbm > -130.0 && phy->avg_snr_db > -30.0) { + if (phy->avg_rsrp_dbm > -130.0 && phy->avg_snr_db > -20.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 01cf00700ac9c9be1e8d22ad61381e2d4ce964e7 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 6 Mar 2018 10:55:22 +0000 Subject: [PATCH 191/342] Adding DNS config options --- srsepc/hdr/mme/s1ap_common.h | 1 + srsepc/src/main.cc | 4 +++- srsepc/src/mme/s1ap_nas_transport.cc | 15 ++++++++++----- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index c69eb05d1..145a94225 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -90,6 +90,7 @@ typedef struct{ uint16_t mnc; // BCD-coded with 0xF filler std::string mme_bind_addr; std::string mme_name; + std::string dns_addr; } s1ap_args_t; typedef struct{ diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index 3a931ddd2..c7c9e6057 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -52,7 +52,6 @@ typedef struct { int spgw_hex_limit; std::string hss_level; int hss_hex_limit; - std::string all_level; int all_hex_limit; std::string filename; @@ -83,6 +82,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { string mme_bind_addr; string spgw_bind_addr; string sgi_if_addr; + string dns_addr; string hss_db_file; string hss_auth_algo; string log_filename; @@ -105,6 +105,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { ("mme.mcc", bpo::value(&mcc)->default_value("001"), "Mobile Country Code") ("mme.mnc", bpo::value(&mnc)->default_value("01"), "Mobile Network Code") ("mme.mme_bind_addr", bpo::value(&mme_bind_addr)->default_value("127.0.0.1"),"IP address of MME for S1 connnection") + ("mme.dns_addr", bpo::value(&dns_addr)->default_value("8.8.8.8"),"IP address of the DNS server for the UEs") ("hss.db_file", bpo::value(&hss_db_file)->default_value("ue_db.csv"),".csv file that stores UE's keys") ("hss.auth_algo", bpo::value(&hss_auth_algo)->default_value("milenage"),"HSS uthentication algorithm.") ("spgw.gtpu_bind_addr", bpo::value(&spgw_bind_addr)->default_value("127.0.0.1"),"IP address of SP-GW for the S1-U connection") @@ -205,6 +206,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { args->mme_args.s1ap_args.mme_bind_addr = mme_bind_addr; args->mme_args.s1ap_args.mme_name = mme_name; + args->mme_args.s1ap_args.dns_addr = dns_addr; args->spgw_args.gtpu_bind_addr = spgw_bind_addr; args->spgw_args.sgi_if_addr = sgi_if_addr; args->hss_args.db_file = hss_db_file; diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index f0767292c..ab119041e 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -650,7 +650,7 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, //Delete eNB context and connect. m_s1ap_log->console("Service Request -- User has ECM context already\n"); m_s1ap_log->info("Service Request -- User has ECM context already\n"); - m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); + //m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); int default_bearer_id = 5; m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ue_emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[default_bearer_id],false); } @@ -1622,10 +1622,15 @@ s1ap_nas_transport::pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *u act_def_eps_bearer_context_req.protocol_cnfg_opts.N_opts = 1; act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[0].id = 0x0d; act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[0].len = 4; - act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[0].contents[0] = 8; - act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[0].contents[1] = 8; - act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[0].contents[2] = 8; - act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[0].contents[3] = 8; + + struct sockaddr_in dns_addr; + inet_pton(AF_INET, m_s1ap->m_s1ap_args.dns_addr.c_str(), &(dns_addr.sin_addr)); + + memcpy(act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[0].contents,&dns_addr.sin_addr.s_addr, 4); + //act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[0].contents[0] = 8; + //act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[0].contents[1] = 8; + //act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[0].contents[2] = 8; + //act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[0].contents[3] = 8; //Make sure all unused options are set to false act_def_eps_bearer_context_req.negotiated_qos_present = false; From 206e41a2440f87f30651a66ca54b627f9581a2b0 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 6 Mar 2018 12:37:08 +0100 Subject: [PATCH 192/342] Disable buffer pool timestamps --- lib/include/srslte/common/common.h | 34 ++++++++++++++++-------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/lib/include/srslte/common/common.h b/lib/include/srslte/common/common.h index ddd558016..8089634b7 100644 --- a/lib/include/srslte/common/common.h +++ b/lib/include/srslte/common/common.h @@ -96,6 +96,8 @@ static const char error_text[ERROR_N_ITEMS][20] = { "None", "Can't start", "Already started"}; +//#define ENABLE_TIMESTAMP + /****************************************************************************** * Byte and Bit buffers * @@ -147,33 +149,27 @@ public: } long get_latency_us() { +#ifdef ENABLE_TIMESTAMP if(!timestamp_is_set) return 0; gettimeofday(×tamp[2], NULL); get_time_interval(timestamp); return timestamp[0].tv_usec; +#else + return 0; +#endif } void set_timestamp() { - gettimeofday(×tamp[1], NULL); - timestamp_is_set = true; +#ifdef ENABLE_TIMESTAMP + gettimeofday(×tamp[1], NULL); + timestamp_is_set = true; +#endif } private: - - - void get_time_interval(struct timeval * tdata) { - - tdata[0].tv_sec = tdata[2].tv_sec - tdata[1].tv_sec; - tdata[0].tv_usec = tdata[2].tv_usec - tdata[1].tv_usec; - if (tdata[0].tv_usec < 0) { - tdata[0].tv_sec--; - tdata[0].tv_usec += 1000000; - } - } - struct timeval timestamp[3]; bool timestamp_is_set; byte_buffer_t *next; @@ -215,15 +211,21 @@ struct bit_buffer_t{ } long get_latency_us() { +#ifdef ENABLE_TIMESTAMP if(!timestamp_is_set) return 0; gettimeofday(×tamp[2], NULL); return timestamp[0].tv_usec; +#else + return 0; +#endif } void set_timestamp() { - gettimeofday(×tamp[1], NULL); - timestamp_is_set = true; +#ifdef ENABLE_TIMESTAMP + gettimeofday(×tamp[1], NULL); + timestamp_is_set = true; +#endif } private: From dc65061dbb2ccf0e78abfaea1886ff7e3da7912a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 6 Mar 2018 12:37:45 +0100 Subject: [PATCH 193/342] Print buffer pool status every 10s (Debugging commit) --- lib/include/srslte/common/buffer_pool.h | 3 +++ srsue/hdr/ue.h | 2 ++ srsue/hdr/ue_base.h | 2 ++ srsue/src/main.cc | 3 ++- srsue/src/ue.cc | 4 ++++ 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index 4edc50fc6..035fbc661 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -173,6 +173,9 @@ public: pool->deallocate(b); b = NULL; } + void print_all_buffers() { + pool->print_all_buffers(); + } private: buffer_pool *pool; }; diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index e6c66b540..d1343c68f 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -72,6 +72,8 @@ public: bool is_attached(); void start_plot(); + void print_pool(); + static void rf_msg(srslte_rf_error_t error); // UE metrics interface diff --git a/srsue/hdr/ue_base.h b/srsue/hdr/ue_base.h index 201f63843..7baa0dfc6 100644 --- a/srsue/hdr/ue_base.h +++ b/srsue/hdr/ue_base.h @@ -157,6 +157,8 @@ public: virtual bool is_attached() = 0; virtual void start_plot() = 0; + virtual void print_pool() = 0; + virtual void radio_overflow() = 0; void handle_rf_msg(srslte_rf_error_t error); diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 1cac2092d..e687756ed 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -474,7 +474,8 @@ int main(int argc, char *argv[]) plot_started = true; } } - sleep(1); + ue->print_pool(); + sleep(10); } pthread_cancel(input); metricshub.stop(); diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 23175fa46..e9afcec41 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -278,6 +278,10 @@ void ue::start_plot() { phy.start_plot(); } +void ue::print_pool() { + byte_buffer_pool::get_instance()->print_all_buffers(); +} + bool ue::get_metrics(ue_metrics_t &m) { m.rf = rf_metrics; From 8f028e34f30f8f14e902a5ee2b44d6ce8fa686b2 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 6 Mar 2018 12:39:29 +0100 Subject: [PATCH 194/342] Do not deallocate BCCH buffer in dl_harq --- srsue/hdr/mac/dl_harq.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index 9d7d8f48e..f4c557898 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -226,7 +226,9 @@ private: is_first_tb = true; ack = false; if (payload_buffer_ptr) { - harq_entity->demux_unit->deallocate(payload_buffer_ptr); + if (pid != HARQ_BCCH_PID) { + harq_entity->demux_unit->deallocate(payload_buffer_ptr); + } payload_buffer_ptr = NULL; } bzero(&cur_grant, sizeof(Tgrant)); @@ -342,7 +344,7 @@ private: harq_entity->nof_pkts++); } } - } else { + } else if (pid != HARQ_BCCH_PID) { harq_entity->demux_unit->deallocate(payload_buffer_ptr); } From 0ce4e30905597f36e08d1fad6e43a466e526f15a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 6 Mar 2018 12:40:34 +0100 Subject: [PATCH 195/342] Minor looging edits --- srsue/src/phy/phch_recv.cc | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index b05a88205..7d9c1bff2 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -142,8 +142,8 @@ void phch_recv::reset() void phch_recv::radio_error() { log_h->error("SYNC: Receiving from radio.\n"); - phy_state = CELL_SEARCH; reset(); + phy_state = CELL_SEARCH; // Need to find a method to effectively reset radio, reloading the driver does not work radio_h->reset(); } @@ -257,20 +257,20 @@ void phch_recv::force_freq(float dl_freq, float ul_freq) { void phch_recv::reset_sync() { + Info("SYNC: Reset. Going to Cell Select\n"); sfn_p.reset(); search_p.reset(); measure_p.reset(); srslte_ue_sync_reset(&ue_sync); - Info("----- PHY RESET----\n"); phy_state = CELL_SELECT; } void phch_recv::cell_search_inc() { - Info("cell_search_inc, cur_idx=%d, size=%d\n", cur_earfcn_index, earfcn.size()); cur_earfcn_index++; if (cur_earfcn_index >= 0) { if (cur_earfcn_index >= (int) earfcn.size()) { + Info("SYNC: Cell Search finished. Going to IDLE\n"); cur_earfcn_index = 0; phy_state = IDLE; rrc->earfcn_end(); @@ -346,8 +346,9 @@ bool phch_recv::cell_handover(srslte_cell_t cell) } /* interface from higher layers to select a new cell */ -void phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { - +void phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) +{ + Info("SYNC: Cell Reselect to EARFCN=%d, PCI=%d\n", earfcn, cell.id); new_earfcn = earfcn; new_cell = cell; phy_state = CELL_RESELECT; @@ -359,7 +360,6 @@ void phch_recv::cell_reselect() uint32_t earfcn = new_earfcn; srslte_cell_t cell = new_cell; - Info("Reset from cell_reselect\n"); reset_sync(); // If we are already in the new cell, just resynchronize @@ -529,11 +529,12 @@ void phch_recv::run_thread() { case search::CELL_FOUND: if (!srslte_cell_isvalid(&cell)) { - Error("SYNC: Detected invalid cell\n"); + Error("SYNC: Detected invalid cell. Going to IDLE\n"); phy_state = IDLE; break; } if (set_cell()) { + Info("SYNC: Setting sampling rate and going to Cell Select\n"); set_sampling_rate(); phy_state = CELL_SELECT; } @@ -973,7 +974,7 @@ phch_recv::sfn_sync::ret_code phch_recv::sfn_sync::run_subframe(srslte_cell_t *c } } } else { - Info("SYNC: PSS/SSS not found...\n"); + Debug("SYNC: PSS/SSS not found...\n"); } cnt++; From acd78dbb8580c5f6afa52729ec2974e85f086b14 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 6 Mar 2018 12:40:55 +0100 Subject: [PATCH 196/342] Change in-sync snr threshold and pass PCCH only if ack=true --- srsue/src/phy/phch_worker.cc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index de73764f4..66c8a0d7c 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -397,7 +397,9 @@ void phch_worker::work_imp() if (!dl_action.generate_ack_callback) { if (dl_mac_grant.rnti_type == SRSLTE_RNTI_PCH && dl_action.decode_enabled[0]) { - phy->mac->pch_decoded_ok(dl_mac_grant.n_bytes[0]); + if (dl_ack[0]) { + phy->mac->pch_decoded_ok(dl_mac_grant.n_bytes[0]); + } } else if (!rar_delivered) { for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { if (dl_action.decode_enabled[tb]) { @@ -410,7 +412,7 @@ void phch_worker::work_imp() update_measurements(); if (chest_ok) { - if (phy->avg_rsrp_dbm > -130.0 && phy->avg_snr_db > -30.0) { + if (phy->avg_rsrp_dbm > -130.0 && phy->avg_snr_db > -20.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(); @@ -519,11 +521,16 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) srslte_dci_msg_t dci_msg; srslte_ra_dl_dci_t dci_unpacked; - - Debug("Looking for RNTI=0x%x\n", dl_rnti); + + if (type == SRSLTE_RNTI_RAR) { + Info("Looking for RNTI=0x%x\n", dl_rnti); + } if (srslte_ue_dl_find_dl_dci_type(&ue_dl, phy->config->dedicated.antenna_info_explicit_value.tx_mode, cfi, tti%10, dl_rnti, type, &dci_msg) != 1) { + if (type == SRSLTE_RNTI_RAR) { + Info("RAR not found\n"); + } return false; } From 390a463d9f1fb2ed7f8d0fbe62ff0f74d3c94498 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 6 Mar 2018 12:41:44 +0100 Subject: [PATCH 197/342] Check for PDU allocation and add warnings --- lib/src/upper/pdcp.cc | 12 ++++++++++-- lib/src/upper/rlc.cc | 37 +++++++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index 188c56c97..cb3ec7d84 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -92,8 +92,12 @@ bool pdcp::is_drb_enabled(uint32_t lcid) void pdcp::write_sdu(uint32_t lcid, byte_buffer_t *sdu) { - if(valid_lcid(lcid)) + if(valid_lcid(lcid)) { pdcp_array[lcid].write_sdu(sdu); + } else { + pdcp_log->warning("Writing sdu: lcid=%d. Deallocating sdu\n", lcid); + byte_buffer_pool::get_instance()->deallocate(sdu); + } } void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg) @@ -149,8 +153,12 @@ void pdcp::enable_encryption(uint32_t lcid) *******************************************************************************/ void pdcp::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { - if(valid_lcid(lcid)) + if(valid_lcid(lcid)) { pdcp_array[lcid].write_pdu(pdu); + } else { + pdcp_log->warning("Writing pdu: lcid=%d. Deallocating pdu\n", lcid); + byte_buffer_pool::get_instance()->deallocate(pdu); + } } void pdcp::write_pdu_bcch_bch(byte_buffer_t *sdu) diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index a626f3002..e771c34a2 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -187,10 +187,14 @@ void rlc::write_pdu_bcch_bch(uint8_t *payload, uint32_t nof_bytes) rlc_log->info_hex(payload, nof_bytes, "BCCH BCH message received."); dl_tput_bytes[0] += nof_bytes; byte_buffer_t *buf = pool_allocate; - memcpy(buf->msg, payload, nof_bytes); - buf->N_bytes = nof_bytes; - buf->set_timestamp(); - pdcp->write_pdu_bcch_bch(buf); + if (buf) { + memcpy(buf->msg, payload, nof_bytes); + buf->N_bytes = nof_bytes; + buf->set_timestamp(); + pdcp->write_pdu_bcch_bch(buf); + } else { + rlc_log->error("Fatal error: Out of buffers from the pool in write_pdu_bcch_bch()\n"); + } } void rlc::write_pdu_bcch_dlsch(uint8_t *payload, uint32_t nof_bytes) @@ -198,10 +202,14 @@ void rlc::write_pdu_bcch_dlsch(uint8_t *payload, uint32_t nof_bytes) rlc_log->info_hex(payload, nof_bytes, "BCCH TXSCH message received."); dl_tput_bytes[0] += nof_bytes; byte_buffer_t *buf = pool_allocate; - memcpy(buf->msg, payload, nof_bytes); - buf->N_bytes = nof_bytes; - buf->set_timestamp(); - pdcp->write_pdu_bcch_dlsch(buf); + if (buf) { + memcpy(buf->msg, payload, nof_bytes); + buf->N_bytes = nof_bytes; + buf->set_timestamp(); + pdcp->write_pdu_bcch_dlsch(buf); + } else { + rlc_log->error("Fatal error: Out of buffers from the pool in write_pdu_bcch_dlsch()\n"); + } } void rlc::write_pdu_pcch(uint8_t *payload, uint32_t nof_bytes) @@ -209,10 +217,14 @@ void rlc::write_pdu_pcch(uint8_t *payload, uint32_t nof_bytes) rlc_log->info_hex(payload, nof_bytes, "PCCH message received."); dl_tput_bytes[0] += nof_bytes; byte_buffer_t *buf = pool_allocate; - memcpy(buf->msg, payload, nof_bytes); - buf->N_bytes = nof_bytes; - buf->set_timestamp(); - pdcp->write_pdu_pcch(buf); + if (buf) { + memcpy(buf->msg, payload, nof_bytes); + buf->N_bytes = nof_bytes; + buf->set_timestamp(); + pdcp->write_pdu_pcch(buf); + } else { + rlc_log->error("Fatal error: Out of buffers from the pool in write_pdu_pcch()\n"); + } } /******************************************************************************* @@ -281,6 +293,7 @@ void rlc::add_bearer(uint32_t lcid, srslte_rlc_config_t cnfg) bool rlc::valid_lcid(uint32_t lcid) { if(lcid >= SRSLTE_N_RADIO_BEARERS) { + rlc_log->warning("Invalid LCID=%d\n", lcid); return false; } else if(!rlc_array[lcid].active()) { return false; From be959d0575e8f7aec63fdd0d95bcfd0f99d7392a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 6 Mar 2018 12:46:02 +0100 Subject: [PATCH 198/342] Fix several pool leaks in RRC/NAS --- srsue/hdr/upper/rrc.h | 16 +++++----- srsue/src/upper/nas.cc | 26 +++++++++------- srsue/src/upper/rrc.cc | 69 ++++++++++++++++++++---------------------- 3 files changed, 56 insertions(+), 55 deletions(-) diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 926e2bebe..55ee21097 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -295,9 +295,9 @@ private: LIBLTE_RRC_DL_CCCH_MSG_STRUCT dl_ccch_msg; LIBLTE_RRC_DL_DCCH_MSG_STRUCT dl_dcch_msg; - byte_buffer_t* byte_align_and_pack(byte_buffer_t *pdu = NULL); - void send_ul_ccch_msg(byte_buffer_t *pdu = NULL); - void send_ul_dcch_msg(byte_buffer_t *pdu = NULL); + byte_buffer_t* byte_align_and_pack(); + void send_ul_ccch_msg(); + void send_ul_dcch_msg(); srslte::bit_buffer_t bit_buf; pthread_mutex_t mutex; @@ -532,10 +532,10 @@ private: void send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause, uint16_t crnti); void send_con_restablish_complete(); void send_con_setup_complete(byte_buffer_t *nas_msg); - void send_ul_info_transfer(uint32_t lcid, byte_buffer_t *sdu); - void send_security_mode_complete(uint32_t lcid, byte_buffer_t *pdu); - void send_rrc_con_reconfig_complete(byte_buffer_t *pdu); - void send_rrc_ue_cap_info(byte_buffer_t *pdu); + void send_ul_info_transfer(byte_buffer_t *nas_msg); + void send_security_mode_complete(); + void send_rrc_con_reconfig_complete(); + void send_rrc_ue_cap_info(); // Parsers void parse_dl_ccch(byte_buffer_t *pdu); @@ -562,7 +562,7 @@ private: void apply_sib2_configs(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2); void handle_con_setup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *setup); void handle_con_reest(LIBLTE_RRC_CONNECTION_REESTABLISHMENT_STRUCT *setup); - void handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *reconfig, byte_buffer_t *pdu); + void handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *reconfig); void add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg); void add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg); void release_drb(uint8_t lcid); diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 8a05595c7..42dae8fc1 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -222,7 +222,7 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { default: nas_log->error("Not handling NAS message with SEC_HDR_TYPE=%02X\n", sec_hdr_type); pool->deallocate(pdu); - break; + return; } // Write NAS pcap @@ -266,7 +266,7 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { default: nas_log->error("Not handling NAS message with MSG_TYPE=%02X\n", msg_type); pool->deallocate(pdu); - break; + return; } } @@ -547,6 +547,8 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) { act_def_eps_bearer_context_accept.protocol_cnfg_opts_present = false; liblte_mme_pack_activate_default_eps_bearer_context_accept_msg(&act_def_eps_bearer_context_accept, &attach_complete.esm_msg); + + pdu->reset(); liblte_mme_pack_attach_complete_msg(&attach_complete, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, ctxt.tx_count, @@ -762,36 +764,37 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu) } // Send response - byte_buffer_t *sdu = pool_allocate; + pdu->reset(); liblte_mme_pack_security_mode_complete_msg(&sec_mode_comp, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT, ctxt.tx_count, - (LIBLTE_BYTE_MSG_STRUCT *) sdu); + (LIBLTE_BYTE_MSG_STRUCT *) pdu); if(pcap != NULL) { - pcap->write_nas(sdu->msg, sdu->N_bytes); + pcap->write_nas(pdu->msg, pdu->N_bytes); } - cipher_encrypt(sdu); + cipher_encrypt(pdu); integrity_generate(&k_nas_int[16], ctxt.tx_count, SECURITY_DIRECTION_UPLINK, - &sdu->msg[5], - sdu->N_bytes - 5, - &sdu->msg[1]); + &pdu->msg[5], + pdu->N_bytes - 5, + &pdu->msg[1]); nas_log->info("Sending Security Mode Complete nas_current_ctxt.tx_count=%d, RB=%s\n", ctxt.tx_count, rrc->get_rb_name(lcid).c_str()); - rrc->write_sdu(lcid, sdu); + rrc->write_sdu(lcid, pdu); ctxt.tx_count++; pool->deallocate(pdu); } void nas::parse_service_reject(uint32_t lcid, byte_buffer_t *pdu) { nas_log->error("TODO:parse_service_reject\n"); + pool->deallocate(pdu); } void nas::parse_esm_information_request(uint32_t lcid, byte_buffer_t *pdu) { nas_log->error("TODO:parse_esm_information_request\n"); - + pool->deallocate(pdu); } void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *pdu) { @@ -800,6 +803,7 @@ void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *pdu) { nas_log->info("Received EMM Information: %s\n", str.c_str()); nas_log->console("%s\n", str.c_str()); ctxt.rx_count++; + pool->deallocate(pdu); } /******************************************************************************* diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 11cb432fa..7c2798658 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1070,34 +1070,36 @@ void rrc::send_con_setup_complete(byte_buffer_t *nas_msg) { send_ul_dcch_msg(); } -void rrc::send_ul_info_transfer(uint32_t lcid, byte_buffer_t *sdu) { +void rrc::send_ul_info_transfer(byte_buffer_t *nas_msg) { rrc_log->debug("Preparing RX Info Transfer\n"); // Prepare RX INFO packet ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_UL_INFO_TRANSFER; ul_dcch_msg.msg.ul_info_transfer.dedicated_info_type = LIBLTE_RRC_UL_INFORMATION_TRANSFER_TYPE_NAS; - memcpy(ul_dcch_msg.msg.ul_info_transfer.dedicated_info.msg, sdu->msg, sdu->N_bytes); - ul_dcch_msg.msg.ul_info_transfer.dedicated_info.N_bytes = sdu->N_bytes; + memcpy(ul_dcch_msg.msg.ul_info_transfer.dedicated_info.msg, nas_msg->msg, nas_msg->N_bytes); + ul_dcch_msg.msg.ul_info_transfer.dedicated_info.N_bytes = nas_msg->N_bytes; - send_ul_dcch_msg(sdu); + pool->deallocate(nas_msg); + + send_ul_dcch_msg(); } -void rrc::send_security_mode_complete(uint32_t lcid, byte_buffer_t *pdu) { +void rrc::send_security_mode_complete() { rrc_log->debug("Preparing Security Mode Complete\n"); ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_SECURITY_MODE_COMPLETE; ul_dcch_msg.msg.security_mode_complete.rrc_transaction_id = transaction_id; - send_ul_dcch_msg(pdu); + send_ul_dcch_msg(); } -void rrc::send_rrc_con_reconfig_complete(byte_buffer_t *pdu) { +void rrc::send_rrc_con_reconfig_complete() { rrc_log->debug("Preparing RRC Connection Reconfig Complete\n"); ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_RRC_CON_RECONFIG_COMPLETE; ul_dcch_msg.msg.rrc_con_reconfig_complete.rrc_transaction_id = transaction_id; - send_ul_dcch_msg(pdu); + send_ul_dcch_msg(); } bool rrc::ho_prepare() { @@ -1177,7 +1179,7 @@ bool rrc::ho_prepare() { k_rrc_enc, k_rrc_int, k_up_enc, k_up_int, cipher_algo, integ_algo); pdcp->config_security_all(k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); - send_rrc_con_reconfig_complete(NULL); + send_rrc_con_reconfig_complete(); } return true; } @@ -1229,15 +1231,14 @@ void rrc::ho_failed() { send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_HANDOVER_FAILURE, ho_src_rnti); } -void rrc::handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *reconfig, - byte_buffer_t *pdu) { +void rrc::handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *reconfig) { uint32_t i; if (reconfig->mob_ctrl_info_present) { if (reconfig->mob_ctrl_info.target_pci == phy->get_current_pci()) { rrc_log->warning("Received HO command to own cell\n"); - send_rrc_con_reconfig_complete(pdu); + send_rrc_con_reconfig_complete(); } else { rrc_log->info("Received HO command to target PCell=%d\n", reconfig->mob_ctrl_info.target_pci); rrc_log->console("Received HO command to target PCell=%d, NCC=%d\n", @@ -1259,7 +1260,7 @@ void rrc::handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGU measurements.parse_meas_config(&reconfig->meas_cnfg); } - send_rrc_con_reconfig_complete(pdu); + send_rrc_con_reconfig_complete(); byte_buffer_t *nas_sdu; for (i = 0; i < reconfig->N_ded_info_nas; i++) { @@ -1318,10 +1319,10 @@ void rrc::leave_connected() * *******************************************************************************/ void rrc::write_pdu_bcch_bch(byte_buffer_t *pdu) { - pool->deallocate(pdu); if (state == RRC_STATE_PLMN_SELECTION) { // Do we need to do something with BCH? rrc_log->info_hex(pdu->msg, pdu->N_bytes, "BCCH BCH message received."); + pool->deallocate(pdu); } else { rrc_log->warning("Received BCCH BCH in incorrect state\n"); } @@ -1523,7 +1524,7 @@ void rrc::write_pdu_pcch(byte_buffer_t *pdu) { * * *******************************************************************************/ -byte_buffer_t* rrc::byte_align_and_pack(byte_buffer_t *pdu) +byte_buffer_t* rrc::byte_align_and_pack() { // Byte align and pack the message bits for PDCP if ((bit_buf.N_bits % 8) != 0) { @@ -1533,15 +1534,8 @@ byte_buffer_t* rrc::byte_align_and_pack(byte_buffer_t *pdu) } // Reset and reuse sdu buffer if provided - byte_buffer_t *pdcp_buf = pdu; - + byte_buffer_t *pdcp_buf = pool_allocate; if (pdcp_buf) { - pdcp_buf->reset(); - } else { - pdcp_buf = pool_allocate; - } - - if (pdcp_buf != NULL) { srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits); pdcp_buf->N_bytes = bit_buf.N_bits / 8; pdcp_buf->set_timestamp(); @@ -1551,10 +1545,10 @@ byte_buffer_t* rrc::byte_align_and_pack(byte_buffer_t *pdu) return pdcp_buf; } -void rrc::send_ul_ccch_msg(byte_buffer_t *pdu) +void rrc::send_ul_ccch_msg() { liblte_rrc_pack_ul_ccch_msg(&ul_ccch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); - pdu = byte_align_and_pack(pdu); + byte_buffer_t *pdu = byte_align_and_pack(); if (pdu) { // Set UE contention resolution ID in MAC uint64_t uecri = 0; @@ -1572,11 +1566,10 @@ void rrc::send_ul_ccch_msg(byte_buffer_t *pdu) } } -void rrc::send_ul_dcch_msg(byte_buffer_t *pdu) +void rrc::send_ul_dcch_msg() { liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); - - pdu = byte_align_and_pack(pdu); + byte_buffer_t *pdu = byte_align_and_pack(); if (pdu) { rrc_log->info("Sending %s\n", liblte_rrc_ul_dcch_msg_type_text[ul_dcch_msg.msg_type]); pdcp->write_sdu(RB_ID_SRB1, pdu); @@ -1591,7 +1584,7 @@ void rrc::write_sdu(uint32_t lcid, byte_buffer_t *sdu) { send_con_setup_complete(sdu); break; case RRC_STATE_CONNECTED: - send_ul_info_transfer(lcid, sdu); + send_ul_info_transfer(sdu); break; default: rrc_log->error("SDU received from NAS while RRC state = %s\n", rrc_state_text[state]); @@ -1665,11 +1658,15 @@ void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) { get_rb_name(lcid).c_str(), liblte_rrc_dl_dcch_msg_type_text[dl_dcch_msg.msg_type]); - // Reset and reuse pdu buffer if possible - pdu->reset(); + pool->deallocate(pdu); switch (dl_dcch_msg.msg_type) { case LIBLTE_RRC_DL_DCCH_MSG_TYPE_DL_INFO_TRANSFER: + pdu = pool_allocate; + if (!pdu) { + rrc_log->error("Fatal error: out of buffers in pool\n"); + return; + } memcpy(pdu->msg, dl_dcch_msg.msg.dl_info_transfer.dedicated_info.msg, dl_dcch_msg.msg.dl_info_transfer.dedicated_info.N_bytes); pdu->N_bytes = dl_dcch_msg.msg.dl_info_transfer.dedicated_info.N_bytes; @@ -1696,18 +1693,18 @@ void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) { // Configure PDCP for security pdcp->config_security(lcid, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); pdcp->enable_integrity(lcid); - send_security_mode_complete(lcid, pdu); + send_security_mode_complete(); pdcp->enable_encryption(lcid); break; case LIBLTE_RRC_DL_DCCH_MSG_TYPE_RRC_CON_RECONFIG: transaction_id = dl_dcch_msg.msg.rrc_con_reconfig.rrc_transaction_id; - handle_rrc_con_reconfig(lcid, &dl_dcch_msg.msg.rrc_con_reconfig, pdu); + handle_rrc_con_reconfig(lcid, &dl_dcch_msg.msg.rrc_con_reconfig); break; case LIBLTE_RRC_DL_DCCH_MSG_TYPE_UE_CAPABILITY_ENQUIRY: transaction_id = dl_dcch_msg.msg.ue_cap_enquiry.rrc_transaction_id; for (uint32_t i = 0; i < dl_dcch_msg.msg.ue_cap_enquiry.N_ue_cap_reqs; i++) { if (LIBLTE_RRC_RAT_TYPE_EUTRA == dl_dcch_msg.msg.ue_cap_enquiry.ue_capability_request[i]) { - send_rrc_ue_cap_info(pdu); + send_rrc_ue_cap_info(); break; } } @@ -1743,7 +1740,7 @@ void rrc::enable_capabilities() { phy->set_config_64qam_en(enable_ul_64); } -void rrc::send_rrc_ue_cap_info(byte_buffer_t *pdu) { +void rrc::send_rrc_ue_cap_info() { rrc_log->debug("Preparing UE Capability Info\n"); ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_UE_CAPABILITY_INFO; @@ -1792,7 +1789,7 @@ void rrc::send_rrc_ue_cap_info(byte_buffer_t *pdu) { liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); - send_ul_dcch_msg(pdu); + send_ul_dcch_msg(); } From b5166e10cd32d77a7744de773cbed9068ebd053a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 6 Mar 2018 13:18:25 +0100 Subject: [PATCH 199/342] Do not restart insync/outsync counters after multiple events --- srsue/src/phy/phch_recv.cc | 4 ++-- srsue/src/phy/phch_worker.cc | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 7d9c1bff2..ecd2cf241 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -705,23 +705,23 @@ void phch_recv::run_thread() } void phch_recv::in_sync() { - out_of_sync_cnt = 0; in_sync_cnt++; // Send RRC in-sync signal after 100 ms consecutive subframes if (in_sync_cnt == NOF_IN_SYNC_SF) { rrc->in_sync(); in_sync_cnt = 0; + out_of_sync_cnt = 0; } } // Out of sync called by worker or phch_recv every 1 or 5 ms void phch_recv::out_of_sync() { - in_sync_cnt = 0; // Send RRC out-of-sync signal after 200 ms consecutive subframes out_of_sync_cnt++; if (out_of_sync_cnt >= NOF_OUT_OF_SYNC_SF) { rrc->out_of_sync(); out_of_sync_cnt = 0; + in_sync_cnt = 0; } } diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 66c8a0d7c..88c9b54c8 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -412,13 +412,13 @@ void phch_worker::work_imp() update_measurements(); if (chest_ok) { - if (phy->avg_rsrp_dbm > -130.0 && phy->avg_snr_db > -20.0) { + if (phy->avg_rsrp_dbm > -130.0 && phy->avg_snr_db > -10.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); + phy->avg_snr_db, phy->avg_rsrp_dbm); chest_loop->in_sync(); } else { log_h->warning("SNR=%.1f dB RSRP=%.1f dBm, sync=out-of-sync from channel estimator\n", - 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)), phy->avg_rsrp_dbm); + phy->avg_snr_db, phy->avg_rsrp_dbm); chest_loop->out_of_sync(); } } From 69a2542e0f4bda7b8d83ab7dd714bddb18236a85 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 6 Mar 2018 13:30:52 +0100 Subject: [PATCH 200/342] Fixed deallocating PDU in NAS too early --- srsue/src/upper/nas.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 0123d106b..0a5b597e4 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -784,7 +784,6 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu) rrc->get_rb_name(lcid).c_str()); rrc->write_sdu(lcid, pdu); ctxt.tx_count++; - pool->deallocate(pdu); } void nas::parse_service_reject(uint32_t lcid, byte_buffer_t *pdu) { From fce672954edde1a397d4264a3888a98c66a26d2b Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 6 Mar 2018 13:37:20 +0100 Subject: [PATCH 201/342] Minor edit to SNR-to-CQI table --- lib/src/phy/phch/cqi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/phch/cqi.c b/lib/src/phy/phch/cqi.c index 522cdf10b..683144439 100644 --- a/lib/src/phy/phch/cqi.c +++ b/lib/src/phy/phch/cqi.c @@ -407,7 +407,7 @@ float srslte_cqi_to_coderate(uint32_t cqi) { * Table III. */ // From paper -static float cqi_to_snr_table[15] = { 1.95, 4, 6, 8, 10, 11.95, 14.05, 16, 17.9, 19.9, 21.5, 23.45, 25.0, 27.30, 29}; +static float cqi_to_snr_table[15] = { 1.95, 4, 6, 8, 10, 11.95, 14.05, 16, 17.9, 20.9, 22.5, 24.75, 25.5, 27.30, 29}; // From experimental measurements @ 5 MHz //static float cqi_to_snr_table[15] = { 1, 1.75, 3, 4, 5, 6, 7.5, 9, 11.5, 13.0, 15.0, 18, 20, 22.5, 26.5}; From 5a8454f5a8a0511cd3726f0e8b0eac8b86bed1d0 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 6 Mar 2018 13:44:19 +0100 Subject: [PATCH 202/342] Fix for staying on PLMN search after disconnect --- srsue/src/phy/phch_worker.cc | 2 +- srsue/src/upper/rrc.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 88c9b54c8..4546788ec 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -529,7 +529,7 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) if (srslte_ue_dl_find_dl_dci_type(&ue_dl, phy->config->dedicated.antenna_info_explicit_value.tx_mode, cfi, tti%10, dl_rnti, type, &dci_msg) != 1) { if (type == SRSLTE_RNTI_RAR) { - Info("RAR not found\n"); + Info("RAR not found, SNR=%.1f dB\n", 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest))); } return false; } diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 7c2798658..37ae14e8c 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -767,9 +767,9 @@ void rrc::earfcn_end() { rrc_log->info("Finished searching cells in EARFCN set while in state %s\n", rrc_state_text[state]); // If searching for PLMN, indicate NAS we scanned all frequencies - if (state == RRC_STATE_PLMN_SELECTION) { + if (state >= RRC_STATE_PLMN_SELECTION && state < RRC_STATE_CONNECTING) { nas->plmn_search_end(); - } else if (state == RRC_STATE_CONNECTED) { + } else if (state >= RRC_STATE_CONNECTING && state < RRC_STATE_LEAVE_CONNECTED) { leave_connected(); } } From add125a01f4884d279f291b899595f9665b8990b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 12:26:49 +0100 Subject: [PATCH 203/342] check expiration of poll_retx_timer and schedule retx if needed --- lib/src/upper/rlc_am.cc | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index f4dced1ec..e6e1ff279 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -198,7 +198,7 @@ uint32_t rlc_am::get_bearer() void rlc_am::write_sdu(byte_buffer_t *sdu) { tx_sdu_queue.write(sdu); - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, tx_sdu_len=%d", rrc->get_rb_name(lcid).c_str(), tx_sdu_queue.size()); + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, tx_sdu_queue_len=%d", rrc->get_rb_name(lcid).c_str(), tx_sdu_queue.size()); } /**************************************************************************** @@ -273,6 +273,27 @@ uint32_t rlc_am::get_buffer_state() goto unlock_and_return; } + // check if pollRetx timer expired (Section 5.2.2.3 in TS 36.322) + if (poll_retx()) { + // if both tx and retx buffer are empty, retransmit next PDU to be ack'ed + log->info("Poll reTx timer expired (lcid=%d)\n", lcid); + if ((tx_window.size() > 0 && retx_queue.size() == 0 && tx_sdu_queue.size() == 0)) { + std::map::iterator it = tx_window.find(vt_s - 1); + if (it != tx_window.end()) { + log->info("Schedule last PDU (SN=%d) for reTx.\n", vt_s - 1); + rlc_amd_retx_t retx; + retx.is_segment = false; + retx.so_start = 0; + retx.so_end = tx_window[vt_s - 1].buf->N_bytes; + retx.sn = vt_s - 1; + retx_queue.push_back(retx); + } else { + log->error("Found invalid PDU in tx_window.\n"); + } + poll_retx_timeout.start(cfg.t_poll_retx); + } + } + // Bytes needed for retx if(retx_queue.size() > 0) { rlc_amd_retx_t retx = retx_queue.front(); From 853f7746074ac5e4d33edd9f281c6706a36028c8 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 13:59:29 +0100 Subject: [PATCH 204/342] add threaded timeout test --- lib/include/srslte/common/timeout.h | 9 ++++- lib/test/common/timeout_test.cc | 61 ++++++++++++++++++++++++++--- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/lib/include/srslte/common/timeout.h b/lib/include/srslte/common/timeout.h index 2c9560729..4174b0237 100644 --- a/lib/include/srslte/common/timeout.h +++ b/lib/include/srslte/common/timeout.h @@ -84,7 +84,6 @@ public: } void thread_func() { - // substract time elapsed until now from timer duration gettimeofday(&start_time[2], NULL); get_time_interval(start_time); @@ -105,6 +104,14 @@ public: return false; } } + int32_t get_msec_to_expire() { + if (running) { + gettimeofday(&start_time[2], NULL); + get_time_interval(start_time); + return (duration_msec*1000 - start_time[0].tv_usec)/1000; + } + return 0; + } bool is_running() { return running; diff --git a/lib/test/common/timeout_test.cc b/lib/test/common/timeout_test.cc index 5c08e1b66..c2451cdb0 100644 --- a/lib/test/common/timeout_test.cc +++ b/lib/test/common/timeout_test.cc @@ -64,7 +64,43 @@ private: pthread_mutex_t mutex; }; -int main(int argc, char **argv) { + +int timer_thread_test() +{ + bool result; + uint32_t id = 0; + uint32_t duration_msec = 5; + uint32_t result_tolerance = 1; + + callback c; + timeout t; + + gettimeofday(&c.start_time[1], NULL); + t.start(duration_msec); + + while (t.is_running() && !t.expired()) { + printf("time to expire=%dms\n", t.get_msec_to_expire()); + usleep(1000); + } + + gettimeofday(&c.start_time[2], NULL); + get_time_interval(c.start_time); + uint32_t diff_ms = c.start_time[0].tv_usec*1e-3; + printf("Target duration: %dms, started: %ld:%ld, ended: %ld:%ld, actual duration %dms\n", + duration_msec, c.start_time[1].tv_sec, c.start_time[1].tv_usec, c.start_time[2].tv_sec, c.start_time[2].tv_usec, diff_ms); + + result = (duration_msec - result_tolerance <= diff_ms < duration_msec + result_tolerance); + + if(result) { + printf("Timer thread test passed\n"); + return 0; + }else{ + return -1; + } +} + +int single_thread_test() +{ bool result; uint32_t id = 0; uint32_t duration_msec = 5; @@ -84,10 +120,25 @@ int main(int argc, char **argv) { result = (diff_ms == duration_msec); if(result) { - printf("Passed\n"); - exit(0); + printf("Single thread test passed\n"); + return 0; }else{ - printf("Failed\n;"); - exit(1); + return -1; } } + + +int main(int argc, char **argv) +{ + if (single_thread_test()) { + printf("Single thread test failed.\n"); + return -1; + } + + if (timer_thread_test()) { + printf("Timer thread test failed.\n"); + return -1; + } + + return 0; +} From d84f6d3d41b08a634536ee46a1c907b0ee7104c9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 13:59:57 +0100 Subject: [PATCH 205/342] add parameter to change loglevel in rlc am stresser --- lib/test/upper/rlc_am_stress_test.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/test/upper/rlc_am_stress_test.cc b/lib/test/upper/rlc_am_stress_test.cc index bdee2248b..fb83e4cfd 100644 --- a/lib/test/upper/rlc_am_stress_test.cc +++ b/lib/test/upper/rlc_am_stress_test.cc @@ -46,6 +46,7 @@ typedef struct { uint32_t sdu_gen_delay_usec; uint32_t pdu_tx_delay_usec; bool reestablish; + uint32_t log_level; } stress_test_args_t; void parse_args(stress_test_args_t *args, int argc, char *argv[]) { @@ -64,7 +65,8 @@ void parse_args(stress_test_args_t *args, int argc, char *argv[]) { ("sdu_gen_delay", bpo::value(&args->sdu_gen_delay_usec)->default_value(10), "SDU generation delay (usec)") ("pdu_tx_delay", bpo::value(&args->pdu_tx_delay_usec)->default_value(10), "Delay in MAC for transfering PDU from tx'ing RLC to rx'ing RLC (usec)") ("error_rate", bpo::value(&args->error_rate)->default_value(0.1), "Rate at which RLC PDUs are dropped") - ("reestablish", bpo::value(&args->reestablish)->default_value(false), "Mimic RLC reestablish during execution"); + ("reestablish", bpo::value(&args->reestablish)->default_value(false), "Mimic RLC reestablish during execution") + ("loglevel", bpo::value(&args->log_level)->default_value(srslte::LOG_LEVEL_DEBUG), "Log level (1=Error,2=Warning,3=Info,4=Debug"); // these options are allowed on the command line bpo::options_description cmdline_options; @@ -81,6 +83,11 @@ void parse_args(stress_test_args_t *args, int argc, char *argv[]) { cout << common << endl << general << endl; exit(0); } + + if (args->log_level > 4) { + args->log_level = 4; + printf("Set log level to %d (%s)\n", args->log_level, srslte::log_level_text[args->log_level]); + } } class mac_reader @@ -260,8 +267,8 @@ void stress_test(stress_test_args_t args) { 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_level((LOG_LEVEL_ENUM)args.log_level); + log2.set_level((LOG_LEVEL_ENUM)args.log_level); log1.set_hex_limit(-1); log2.set_hex_limit(-1); From 77c8bf08cf5608fee21690ed0162b1d5857c982e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 14:00:29 +0100 Subject: [PATCH 206/342] remove newlines --- lib/src/common/buffer_pool.cc | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/src/common/buffer_pool.cc b/lib/src/common/buffer_pool.cc index e41668abf..3bb191143 100644 --- a/lib/src/common/buffer_pool.cc +++ b/lib/src/common/buffer_pool.cc @@ -54,12 +54,5 @@ void byte_buffer_pool::cleanup(void) } pthread_mutex_unlock(&instance_mutex); } - - - - - - - } // namespace srsue From f5e3049f6376cca927b71542a8edc0487bb9fc36 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 14:46:50 +0100 Subject: [PATCH 207/342] add check for possible buffer pool misallocation in RRC/NAS/GW --- srsue/src/upper/gw.cc | 8 ++++++-- srsue/src/upper/nas.cc | 13 +++++++++++++ srsue/src/upper/rrc.cc | 11 ++++++++--- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/srsue/src/upper/gw.cc b/srsue/src/upper/gw.cc index 65748f57b..fbf4bca9f 100644 --- a/srsue/src/upper/gw.cc +++ b/srsue/src/upper/gw.cc @@ -242,7 +242,11 @@ void gw::run_thread() struct iphdr *ip_pkt; uint32 idx = 0; int32 N_bytes; - srslte::byte_buffer_t *pdu = pool_allocate; + srslte::byte_buffer_t *pdu = pool_allocate; + if (!pdu) { + gw_log->error("Fatal Error: Couldn't allocate PDU in run_thread().\n"); + return; + } const static uint32_t ATTACH_TIMEOUT_MS = 10000; const static uint32_t ATTACH_MAX_ATTEMPTS = 3; @@ -307,7 +311,7 @@ void gw::run_thread() do { pdu = pool_allocate; if (!pdu) { - printf("Not enough buffers in pool\n"); + gw_log->error("Fatal Error: Couldn't allocate PDU in run_thread().\n"); usleep(100000); } } while(!pdu); diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 0a5b597e4..5d766776a 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -812,6 +812,11 @@ void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *pdu) { void nas::send_attach_request() { LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req; byte_buffer_t *msg = pool_allocate; + if (!msg) { + nas_log->error("Fatal Error: Couldn't allocate PDU in send_attach_request().\n"); + return; + } + u_int32_t i; attach_req.eps_attach_type = LIBLTE_MME_EPS_ATTACH_TYPE_EPS_ATTACH; @@ -913,6 +918,10 @@ void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg) { void nas::send_security_mode_reject(uint8_t cause) { byte_buffer_t *msg = pool_allocate; + if (!msg) { + nas_log->error("Fatal Error: Couldn't allocate PDU in send_security_mode_reject().\n"); + return; + } LIBLTE_MME_SECURITY_MODE_REJECT_MSG_STRUCT sec_mode_rej; sec_mode_rej.emm_cause = cause; @@ -928,6 +937,10 @@ void nas::send_identity_response() {} void nas::send_service_request() { byte_buffer_t *msg = pool_allocate; + if (!msg) { + nas_log->error("Fatal Error: Couldn't allocate PDU in send_service_request().\n"); + return; + } // Pack the service request message directly msg->msg[0] = (LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST << 4) | (LIBLTE_MME_PD_EPS_MOBILITY_MANAGEMENT); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 37ae14e8c..56d0eb6ce 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1265,9 +1265,14 @@ void rrc::handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGU byte_buffer_t *nas_sdu; for (i = 0; i < reconfig->N_ded_info_nas; i++) { nas_sdu = pool_allocate; - memcpy(nas_sdu->msg, &reconfig->ded_info_nas_list[i].msg, reconfig->ded_info_nas_list[i].N_bytes); - nas_sdu->N_bytes = reconfig->ded_info_nas_list[i].N_bytes; - nas->write_pdu(lcid, nas_sdu); + if (nas_sdu) { + memcpy(nas_sdu->msg, &reconfig->ded_info_nas_list[i].msg, reconfig->ded_info_nas_list[i].N_bytes); + nas_sdu->N_bytes = reconfig->ded_info_nas_list[i].N_bytes; + nas->write_pdu(lcid, nas_sdu); + } else { + rrc_log->error("Fatal Error: Couldn't allocate PDU in handle_rrc_con_reconfig().\n"); + return; + } } } } From 4575a9e610291846176e3e98a3ca69881738a810 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 15:20:23 +0100 Subject: [PATCH 208/342] add further checks for pool allocate return in srsENB and RLC UM/TM --- lib/src/upper/rlc_tm.cc | 12 ++++++++---- lib/src/upper/rlc_um.cc | 23 ++++++++++++++++++++++- srsenb/src/upper/gtpu.cc | 4 ++++ srsenb/src/upper/s1ap.cc | 32 ++++++++++++++++++++++++++++---- 4 files changed, 62 insertions(+), 9 deletions(-) diff --git a/lib/src/upper/rlc_tm.cc b/lib/src/upper/rlc_tm.cc index bcf3cd20a..b9d41d3f2 100644 --- a/lib/src/upper/rlc_tm.cc +++ b/lib/src/upper/rlc_tm.cc @@ -125,10 +125,14 @@ int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes) void rlc_tm::write_pdu(uint8_t *payload, uint32_t nof_bytes) { byte_buffer_t *buf = pool_allocate; - memcpy(buf->msg, payload, nof_bytes); - buf->N_bytes = nof_bytes; - buf->set_timestamp(); - pdcp->write_pdu(lcid, buf); + if (buf) { + memcpy(buf->msg, payload, nof_bytes); + buf->N_bytes = nof_bytes; + buf->set_timestamp(); + pdcp->write_pdu(lcid, buf); + } else { + log->error("Fatal Error: Couldn't allocate buffer in rlc_tm::write_pdu().\n"); + } } } // namespace srsue diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index a365a4501..647494552 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -448,8 +448,13 @@ void rlc_um::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes) void rlc_um::reassemble_rx_sdus() { - if(!rx_sdu) + if(!rx_sdu) { rx_sdu = pool_allocate; + if (!rx_sdu) { + log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); + return; + } + } // First catch up with lower edge of reordering window while(!inside_reordering_window(vr_ur)) @@ -474,6 +479,10 @@ void rlc_um::reassemble_rx_sdus() rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; + if (!rx_sdu) { + log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); + return; + } } pdu_lost = false; } @@ -494,6 +503,10 @@ void rlc_um::reassemble_rx_sdus() rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; + if (!rx_sdu) { + log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); + return; + } } pdu_lost = false; } @@ -528,6 +541,10 @@ void rlc_um::reassemble_rx_sdus() rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; + if (!rx_sdu) { + log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); + return; + } } pdu_lost = false; } @@ -557,6 +574,10 @@ void rlc_um::reassemble_rx_sdus() rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; + if (!rx_sdu) { + log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); + return; + } } pdu_lost = false; } diff --git a/srsenb/src/upper/gtpu.cc b/srsenb/src/upper/gtpu.cc index 53b7cffdb..2336f9047 100644 --- a/srsenb/src/upper/gtpu.cc +++ b/srsenb/src/upper/gtpu.cc @@ -195,6 +195,10 @@ void gtpu::rem_user(uint16_t rnti) void gtpu::run_thread() { byte_buffer_t *pdu = pool_allocate; + if (!pdu) { + gtpu_log->error("Fatal Error: Couldn't allocate buffer in gtpu::run_thread().\n"); + return; + } run_enable = true; running=true; diff --git a/srsenb/src/upper/s1ap.cc b/srsenb/src/upper/s1ap.cc index 44a564d09..a3d937a57 100644 --- a/srsenb/src/upper/s1ap.cc +++ b/srsenb/src/upper/s1ap.cc @@ -88,6 +88,10 @@ void s1ap::get_metrics(s1ap_metrics_t &m) void s1ap::run_thread() { srslte::byte_buffer_t *pdu = pool_allocate; + if (!pdu) { + s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::run_thread().\n"); + return; + } uint32_t sz = SRSLTE_MAX_BUFFER_SIZE_BYTES - SRSLTE_BUFFER_HEADER_OFFSET; running = true; @@ -514,10 +518,15 @@ bool s1ap::handle_dlnastransport(LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT } srslte::byte_buffer_t *pdu = pool_allocate; - memcpy(pdu->msg, msg->NAS_PDU.buffer, msg->NAS_PDU.n_octets); - pdu->N_bytes = msg->NAS_PDU.n_octets; - rrc->write_dl_info(rnti, pdu); - return true; + if (pdu) { + memcpy(pdu->msg, msg->NAS_PDU.buffer, msg->NAS_PDU.n_octets); + pdu->N_bytes = msg->NAS_PDU.n_octets; + rrc->write_dl_info(rnti, pdu); + return true; + } else { + s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::run_thread().\n"); + return false; + } } bool s1ap::handle_initialctxtsetuprequest(LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *msg) @@ -850,6 +859,11 @@ bool s1ap::send_initial_ctxt_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_I return false; } srslte::byte_buffer_t *buf = pool_allocate; + if (!buf) { + s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_initial_ctxt_setup_response().\n"); + return false; + } + LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu; tx_pdu.ext = false; @@ -896,6 +910,11 @@ bool s1ap::send_erab_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETU return false; } srslte::byte_buffer_t *buf = pool_allocate; + if (!buf) { + s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_erab_setup_response().\n"); + return false; + } + LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu; tx_pdu.ext = false; @@ -942,6 +961,11 @@ bool s1ap::send_initial_ctxt_setup_failure(uint16_t rnti) return false; } srslte::byte_buffer_t *buf = pool_allocate; + if (!buf) { + s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_initial_ctxt_setup_failure().\n"); + return false; + } + LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu; tx_pdu.ext = false; tx_pdu.choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_UNSUCCESSFULOUTCOME; From cd0373c533e3e174ab7e253a8addef18aeb29dbc Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 6 Mar 2018 15:19:47 +0000 Subject: [PATCH 209/342] opt assignment was being erased by bzero call --- lib/src/phy/rf/rf_uhd_imp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index 0370fa700..b4b0cfcd6 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -80,8 +80,8 @@ static void log_overflow(rf_uhd_handler_t *h) { static void log_late(rf_uhd_handler_t *h, bool is_rx) { if (h->uhd_error_handler) { srslte_rf_error_t error; - error.opt = is_rx?1:0; bzero(&error, sizeof(srslte_rf_error_t)); + error.opt = is_rx?1:0; error.type = SRSLTE_RF_ERROR_LATE; h->uhd_error_handler(error); } From 962164277ad90b4c2f70dfab3b0571d6c8311926 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 6 Mar 2018 17:09:59 +0100 Subject: [PATCH 210/342] Normalize CSI to maximum. --- lib/src/phy/phch/pdsch.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index 4cfa5c75c..c59956a71 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -659,8 +659,13 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *c int16_t *e = q->e[codeword_idx]; if (q->csi_enabled) { + const uint32_t csi_max_idx = srslte_vec_max_fi(q->csi[codeword_idx], nbits->nof_bits / qm); + float csi_max = 1.0f; + if (csi_max_idx < nbits->nof_bits / qm) { + csi_max = q->csi[codeword_idx][csi_max_idx]; + } for (int i = 0; i < nbits->nof_bits / qm; i++) { - float csi = q->csi[codeword_idx][i]; + const float csi = q->csi[codeword_idx][i] / csi_max; for (int k = 0; k < qm; k++) { e[qm * i + k] = (int16_t) ((float) e[qm * i + k] * csi); } From b5421301af6acd7358ec050e4334e69b9a0083fc Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 18:45:31 +0100 Subject: [PATCH 211/342] fix mem leak in NAS test --- srsue/test/upper/nas_test.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index 4f4ffb687..bf249f792 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -76,6 +76,7 @@ public: printf("NAS generated SDU (len=%d):\n", sdu->N_bytes); last_sdu_len = sdu->N_bytes; srslte_vec_fprint_byte(stdout, sdu->msg, sdu->N_bytes); + byte_buffer_pool::get_instance()->deallocate(sdu); } std::string get_rb_name(uint32_t lcid) { return std::string("lcid"); } uint32_t get_last_sdu_len() { return last_sdu_len; } From c3088e1d16b6a78a9bdfc95135ec3dd905da21bc Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 20:50:25 +0100 Subject: [PATCH 212/342] add cmake option to enable address sanitizer --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d67985c49..10952a010 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,7 @@ option(ENABLE_BLADERF "Enable BladeRF" ON) option(BUILD_STATIC "Attempt to statically link external deps" OFF) option(RPATH "Enable RPATH" OFF) +option(ENABLE_ASAN "Enable gcc address sanitizer" OFF) option(USE_LTE_RATES "Use standard LTE sampling rates" OFF) @@ -303,6 +304,10 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") if(NOT WIN32) ADD_CXX_COMPILER_FLAG_IF_AVAILABLE(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN) endif(NOT WIN32) + if (ENABLE_ASAN) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + endif (ENABLE_ASAN) endif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") From e933f05933abed155d95670854d2f014c3f2bed6 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 21:34:36 +0100 Subject: [PATCH 213/342] fix memleak in vector test../lib/src/phy/utils/test/vector_test.c --- lib/src/phy/utils/test/vector_test.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/src/phy/utils/test/vector_test.c b/lib/src/phy/utils/test/vector_test.c index 55ff2944e..623fdb526 100644 --- a/lib/src/phy/utils/test/vector_test.c +++ b/lib/src/phy/utils/test/vector_test.c @@ -265,6 +265,7 @@ TEST(srslte_vec_sum_fff, free(x); free(y); + free(z); ) TEST(srslte_vec_sub_fff, @@ -287,6 +288,7 @@ TEST(srslte_vec_sub_fff, free(x); free(y); + free(z); ) TEST(srslte_vec_dot_prod_ccc, @@ -354,6 +356,7 @@ TEST(srslte_vec_prod_ccc, } free(x); + free(y); free(z); ) @@ -407,6 +410,7 @@ TEST(srslte_vec_prod_conj_ccc, } free(x); + free(y); free(z); ) From cae09a8d5832d8a2d802d155281caa856bf08f1b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 21:35:15 +0100 Subject: [PATCH 214/342] fix mem leak in PMCH --- lib/src/phy/phch/pmch.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/src/phy/phch/pmch.c b/lib/src/phy/phch/pmch.c index c1c322f34..ed6bbf2b5 100644 --- a/lib/src/phy/phch/pmch.c +++ b/lib/src/phy/phch/pmch.c @@ -152,9 +152,8 @@ int srslte_pmch_init(srslte_pmch_t *q, uint32_t max_prb) int srslte_pmch_init_multi(srslte_pmch_t *q, uint32_t max_prb, uint32_t nof_rx_antennas) { int ret = SRSLTE_ERROR_INVALID_INPUTS; - int i; - if (q != NULL && + if (q != NULL && nof_rx_antennas <= SRSLTE_MAX_PORTS) { @@ -169,7 +168,7 @@ int srslte_pmch_init_multi(srslte_pmch_t *q, uint32_t max_prb, uint32_t nof_rx_a INFO("Init PMCH: %d PRBs, max_symbols: %d\n", max_prb, q->max_re); - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { if (srslte_modem_table_lte(&q->mod[i], modulations[i])) { goto clean; } @@ -189,7 +188,7 @@ int srslte_pmch_init_multi(srslte_pmch_t *q, uint32_t max_prb, uint32_t nof_rx_a goto clean; } - for (i = 0; i < SRSLTE_MAX_PORTS; i++) { + for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { q->x[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->x[i]) { goto clean; @@ -232,7 +231,7 @@ void srslte_pmch_free(srslte_pmch_t *q) { if (q->d) { free(q->d); } - for (i = 0; i < q->cell.nof_ports; i++) { + for (i = 0; i < SRSLTE_MAX_PORTS; i++) { if (q->x[i]) { free(q->x[i]); } From 4c76e98f9e049dcafe73951fd45549f60950f445 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 21:35:55 +0100 Subject: [PATCH 215/342] fix memleak in DL chest object --- lib/src/phy/ch_estimation/chest_dl.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index 221bac319..ec827ec13 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -88,7 +88,7 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, uint32_t max_prb) goto clean_exit; } - q->mbsfn_refs = calloc(SRSLTE_MAX_MBSFN_AREA_IDS, sizeof(srslte_refsignal_t*)); + q->mbsfn_refs = calloc(SRSLTE_MAX_MBSFN_AREA_IDS, sizeof(srslte_refsignal_t)); if (!q->mbsfn_refs) { fprintf(stderr, "Calloc error initializing mbsfn_refs (%d)\n", ret); goto clean_exit; @@ -169,14 +169,14 @@ clean_exit: void srslte_chest_dl_free(srslte_chest_dl_t *q) { - int i; if(&q->csr_refs) srslte_refsignal_free(&q->csr_refs); if (q->mbsfn_refs) { - for (i=0; imbsfn_refs[i]) { srslte_refsignal_free(q->mbsfn_refs[i]); + free(q->mbsfn_refs[i]); } } free(q->mbsfn_refs); @@ -206,15 +206,18 @@ void srslte_chest_dl_free(srslte_chest_dl_t *q) int srslte_chest_dl_set_mbsfn_area_id(srslte_chest_dl_t *q, uint16_t mbsfn_area_id){ - if(!q->mbsfn_refs[mbsfn_area_id]){ - q->mbsfn_refs[mbsfn_area_id] = calloc(1, sizeof(srslte_refsignal_t)); - } - if(q->mbsfn_refs[mbsfn_area_id]) { - if(srslte_refsignal_mbsfn_init(q->mbsfn_refs[mbsfn_area_id], q->cell, mbsfn_area_id)) { - return SRSLTE_ERROR; + if (mbsfn_area_id < SRSLTE_MAX_MBSFN_AREA_IDS) { + if(!q->mbsfn_refs[mbsfn_area_id]) { + q->mbsfn_refs[mbsfn_area_id] = calloc(1, sizeof(srslte_refsignal_t)); } - } - return SRSLTE_SUCCESS; + if(q->mbsfn_refs[mbsfn_area_id]) { + if(srslte_refsignal_mbsfn_init(q->mbsfn_refs[mbsfn_area_id], q->cell, mbsfn_area_id)) { + return SRSLTE_ERROR; + } + } + return SRSLTE_SUCCESS; + } + return SRSLTE_ERROR; } int srslte_chest_dl_set_cell(srslte_chest_dl_t *q, srslte_cell_t cell) From c6933f53388238491387726f082d14cec3c68f8d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 21:48:44 +0100 Subject: [PATCH 216/342] fix leak in turbocoder test --- lib/src/phy/fec/test/turbocoder_test.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/src/phy/fec/test/turbocoder_test.c b/lib/src/phy/fec/test/turbocoder_test.c index c7ca41fe3..8daeebdb8 100644 --- a/lib/src/phy/fec/test/turbocoder_test.c +++ b/lib/src/phy/fec/test/turbocoder_test.c @@ -71,8 +71,6 @@ int main(int argc, char **argv) { parse_args(argc, argv); - srslte_tcod_gentable(); - srslte_tcod_t tcod; srslte_tcod_init(&tcod, 6144); From 13efa740e846dea1b0b559d1229418d8bd1b1f39 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 6 Mar 2018 22:20:38 +0100 Subject: [PATCH 217/342] Changed logic in RRC/NAS/PHY for cell/plmn search to avoid stucking in IDLE --- lib/include/srslte/interfaces/ue_interfaces.h | 4 +- srsue/hdr/phy/phch_recv.h | 2 +- srsue/hdr/upper/nas.h | 3 +- srsue/hdr/upper/rrc.h | 7 +- srsue/src/phy/phch_recv.cc | 6 +- srsue/src/phy/phch_worker.cc | 4 +- srsue/src/upper/nas.cc | 24 +- srsue/src/upper/rrc.cc | 212 ++++++++++-------- srsue/test/upper/nas_test.cc | 2 +- 9 files changed, 140 insertions(+), 124 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 923111371..b1251c0bb 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -119,7 +119,7 @@ public: virtual uint32_t get_ul_count() = 0; virtual bool get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi) = 0; virtual bool get_k_asme(uint8_t *k_asme_, uint32_t n) = 0; - virtual void plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) = 0; + virtual bool plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) = 0; virtual void plmn_search_end() = 0; }; @@ -173,7 +173,7 @@ public: virtual uint16_t get_mnc() = 0; virtual void enable_capabilities() = 0; virtual void plmn_search() = 0; - virtual void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) = 0; + virtual void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, bool connect_request = false) = 0; virtual std::string get_rb_name(uint32_t lcid) = 0; }; diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index 861d58229..d77e489ae 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -150,7 +150,7 @@ private: srslte_ue_mib_t ue_mib; uint32_t cnt; uint32_t timeout; - const static uint32_t SYNC_SFN_TIMEOUT = 500; + const static uint32_t SYNC_SFN_TIMEOUT = 80; }; // Class to perform cell measurements diff --git a/srsue/hdr/upper/nas.h b/srsue/hdr/upper/nas.h index 6038993e0..8a1fd6ae3 100644 --- a/srsue/hdr/upper/nas.h +++ b/srsue/hdr/upper/nas.h @@ -88,9 +88,10 @@ public: uint32_t get_ul_count(); bool is_attached(); bool is_attaching(); + bool is_data_requested(); bool get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi); bool get_k_asme(uint8_t *k_asme_, uint32_t n); - void plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code); + bool plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code); void plmn_search_end(); // UE interface diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 55ee21097..904ae59db 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -249,7 +249,7 @@ public: void enable_capabilities(); void plmn_search(); - void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id); + void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, bool connect_request); // PHY interface void in_sync(); @@ -324,9 +324,6 @@ private: uint32_t plmn_select_timeout; static const uint32_t RRC_PLMN_SELECT_TIMEOUT = 10000; - uint32_t select_cell_timeout; - static const uint32_t RRC_SELECT_CELL_TIMEOUT = 1000; - uint8_t k_rrc_enc[32]; uint8_t k_rrc_int[32]; uint8_t k_up_enc[32]; @@ -401,7 +398,7 @@ private: uint16_t sysinfo_index; uint32_t last_win_start; - void select_next_cell_in_plmn(); + bool select_next_cell_in_plmn(); LIBLTE_RRC_PLMN_IDENTITY_STRUCT selected_plmn_id; bool thread_running; diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index ecd2cf241..ca6a35772 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -565,8 +565,8 @@ void phch_recv::run_thread() } break; case sfn_sync::TIMEOUT: - log_h->warning("SYNC: Timeout while synchronizing SFN. Going back to cell search\n"); - phy_state = CELL_SEARCH; + log_h->warning("SYNC: Timeout while synchronizing SFN\n"); + rrc->out_of_sync(); break; case sfn_sync::IDLE: break; @@ -1271,7 +1271,7 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset, for (uint32_t sf5_cnt=0;sf5_cnt max_peak && sync_res == SRSLTE_SYNC_FOUND) { diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 4546788ec..2d1b67c48 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -529,7 +529,9 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) if (srslte_ue_dl_find_dl_dci_type(&ue_dl, phy->config->dedicated.antenna_info_explicit_value.tx_mode, cfi, tti%10, dl_rnti, type, &dci_msg) != 1) { if (type == SRSLTE_RNTI_RAR) { - Info("RAR not found, SNR=%.1f dB\n", 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest))); + Info("RAR not found, SNR=%.1f dB, tti=%d, cfi=%d, tx_mode=%d, cell_id=%d\n", + 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)), tti, cfi, + phy->config->dedicated.antenna_info_explicit_value.tx_mode, cell.id); } return false; } diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 0a5b597e4..c25a05125 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -107,8 +107,8 @@ void nas::attach_request() { selecting_plmn = current_plmn; } } else if (state == EMM_STATE_REGISTERED) { - nas_log->info("NAS state is registered, connecting to same PLMN\n"); - rrc->plmn_select(current_plmn); + nas_log->info("NAS state is registered, selecting current PLMN\n"); + rrc->plmn_select(current_plmn, true); } else { nas_log->info("Attach request ignored. State = %s\n", emm_state_text[state]); } @@ -123,12 +123,7 @@ void nas::deattach_request() { * RRC interface ******************************************************************************/ -void nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) { - - // Do not process new PLMN if already selected - if (plmn_selection == PLMN_SELECTED) { - return; - } +bool nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) { // Check if already registered for (uint32_t i=0;iinfo("Found known PLMN Id=%s\n", plmn_id_to_string(plmn_id).c_str()); if (plmn_id.mcc == home_plmn.mcc && plmn_id.mnc == home_plmn.mnc) { nas_log->info("Connecting Home PLMN Id=%s\n", plmn_id_to_string(plmn_id).c_str()); - rrc->plmn_select(plmn_id); + rrc->plmn_select(plmn_id, state == EMM_STATE_REGISTERED_INITIATED); selecting_plmn = plmn_id; + return true; } - return; + return false; } } @@ -152,10 +148,11 @@ void nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_ tracking_area_code); if (plmn_id.mcc == home_plmn.mcc && plmn_id.mnc == home_plmn.mnc) { - rrc->plmn_select(plmn_id); + rrc->plmn_select(plmn_id, state == EMM_STATE_REGISTERED_INITIATED); selecting_plmn = plmn_id; + return true; } - + return false; } // RRC indicates that the UE has gone through all EARFCN and finished PLMN selection @@ -170,7 +167,7 @@ void nas::plmn_search_end() { plmn_id_to_string(home_plmn).c_str(), plmn_id_to_string(known_plmns[0]).c_str()); } - rrc->plmn_select(known_plmns[0]); + rrc->plmn_select(known_plmns[0], state == EMM_STATE_REGISTERED_INITIATED); } else { nas_log->info("Finished searching PLMN in current EARFCN set but no networks were found.\n"); if (state == EMM_STATE_REGISTERED_INITIATED && plmn_selection == PLMN_NOT_SELECTED) { @@ -538,6 +535,7 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) { state = EMM_STATE_REGISTERED; current_plmn = selecting_plmn; + plmn_selection = PLMN_SELECTED; ctxt.rx_count++; diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 37ae14e8c..875785093 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -126,6 +126,8 @@ void rrc::init(phy_interface_rrc *phy_, pending_mob_reconf = false; + connection_requested = false; + // Set default values for all layers set_rrc_default(); set_phy_default(); @@ -184,10 +186,8 @@ void rrc::run_thread() { if (phy->sync_status()) { // If attempting to attach, reselect cell if (nas->is_attaching()) { - sleep(1); - rrc_log->info("RRC IDLE: NAS is attaching and camping on cell, reselecting...\n"); + rrc_log->info("RRC IDLE: NAS has pending data and camping on cell, connecting...\n"); plmn_select_rrc(selected_plmn_id); - connection_requested = true; } // If not camping on a cell } else { @@ -196,7 +196,6 @@ void rrc::run_thread() { rrc_log->info("RRC IDLE: NAS is attached, PHY not synchronized. Re-selecting cell...\n"); plmn_select_rrc(selected_plmn_id); } else if (nas->is_attaching()) { - sleep(1); rrc_log->info("RRC IDLE: NAS is attaching, searching again PLMN\n"); plmn_search(); } @@ -234,16 +233,6 @@ void rrc::run_thread() { state = RRC_STATE_CELL_SELECTED; } } - // Don't time out during reestablishment (T311 running) - if (!mac_timers->timer_get(t311)->is_running() || !phy->sync_status()) { - select_cell_timeout++; - if (select_cell_timeout >= RRC_SELECT_CELL_TIMEOUT) { - rrc_log->info("RRC Cell Selecting: timeout expired. Starting Cell Search...\n"); - select_cell_timeout = 0; - state = RRC_STATE_PLMN_START; - serving_cell->in_sync = false; - } - } break; case RRC_STATE_CELL_SELECTED: @@ -258,9 +247,9 @@ void rrc::run_thread() { con_restablish_cell_reselected(); state = RRC_STATE_CONNECTING; connecting_timeout = 0; - } else if (connection_requested) { - connection_requested = false; + } else if (nas->is_attaching() || connection_requested) { rrc_log->info("RRC Cell Selected: Sending connection request...\n"); + connection_requested = false; send_con_request(); state = RRC_STATE_CONNECTING; connecting_timeout = 0; @@ -442,8 +431,8 @@ void rrc::plmn_search() { /* This is the NAS interface. When NAS requests to select a PLMN we have to * connect to either register or because there is pending higher layer traffic. */ -void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { - connection_requested = true; +void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, bool connect_request) { + connection_requested = connect_request; plmn_select_rrc(plmn_id); } @@ -451,37 +440,41 @@ void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { * selected PLMN */ void rrc::plmn_select_rrc(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { + pthread_mutex_lock(&mutex); + // If already camping on the selected PLMN, select this cell if (state == RRC_STATE_IDLE || state == RRC_STATE_CONNECTED || state == RRC_STATE_PLMN_SELECTION) { if (phy->sync_status() && selected_plmn_id.mcc == plmn_id.mcc && selected_plmn_id.mnc == plmn_id.mnc) { - rrc_log->info("Already camping on selected PLMN, connecting...\n"); + rrc_log->info("Already camping on selected PLMN\n"); } else { selected_plmn_id = plmn_id; - if (serving_cell->plmn_equals(selected_plmn_id)) { - phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); + if (serving_cell->plmn_equals(selected_plmn_id) && serving_cell->in_sync) { + rrc_log->info("PLMN Id=%s selected, Selecting serving cell earfcn=%d, pci=%d\n", + plmn_id_to_string(plmn_id).c_str(), serving_cell->get_earfcn(), serving_cell->phy_cell.id); } else { bool found = false; for (uint32_t i=0;iplmn_equals(selected_plmn_id)) { - rrc_log->info("PLMN Id=%s selected, PCI=%d\n", plmn_id_to_string(plmn_id).c_str(), neighbour_cells[i]->get_pci()); + rrc_log->info("PLMN Id=%s selected, Selecting neighbour cell PCI=%d\n", plmn_id_to_string(plmn_id).c_str(), neighbour_cells[i]->get_pci()); phy->cell_select(neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->phy_cell); found = true; } } if (!found) { - rrc_log->warning("Could not find any cell for the selected PLMN\n"); - state = RRC_STATE_IDLE; + rrc_log->warning("Could not find any cell for the selected PLMN. Searching another PLMN\n"); + plmn_search(); + pthread_mutex_unlock(&mutex); return; } } } state = RRC_STATE_CELL_SELECTING; - select_cell_timeout = 0; } else { rrc_log->warning("Requested PLMN select in incorrect state %s\n", rrc_state_text[state]); } + pthread_mutex_unlock(&mutex); } void rrc::set_serving_cell(uint32_t earfcn, uint32_t pci) { @@ -494,6 +487,7 @@ void rrc::set_serving_cell(uint32_t earfcn, uint32_t pci) { } void rrc::set_serving_cell(uint32_t cell_idx) { + if (cell_idx < neighbour_cells.size()) { // Remove future serving cell from neighbours to make space for current serving cell @@ -529,29 +523,37 @@ void rrc::set_serving_cell(uint32_t cell_idx) { } } -void rrc::select_next_cell_in_plmn() { +bool rrc::select_next_cell_in_plmn() { // Neighbour cells are sorted in descending order of RSRP for (uint32_t i = 0; i < neighbour_cells.size(); i++) { - if (neighbour_cells[i]->plmn_equals(selected_plmn_id) && + if (/*TODO: CHECK that PLMN matches. Currently we don't receive SIB1 of neighbour cells + * neighbour_cells[i]->plmn_equals(selected_plmn_id) && */ neighbour_cells[i]->in_sync) // matches S criteria { - // Try to select Cell - phy->cell_select(neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->phy_cell); - set_serving_cell(i); - rrc_log->info("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", - serving_cell->phy_cell.id, serving_cell->get_earfcn(), - serving_cell->get_cell_id()); - rrc_log->console("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", - serving_cell->phy_cell.id, serving_cell->get_earfcn(), - serving_cell->get_cell_id()); - return; + // If currently connected, verify cell selection criteria + if (!serving_cell->in_sync || + (cell_selection_eval(neighbour_cells[i]->get_rsrp()) && + neighbour_cells[i]->get_rsrp() > serving_cell->get_rsrp() + 5)) + { + // Try to select Cell + set_serving_cell(i); + rrc_log->info("Selected cell idx=%d, PCI=%d, EARFCN=%d\n", + i, serving_cell->phy_cell.id, serving_cell->get_earfcn()); + rrc_log->console("Selected cell PCI=%d, EARFCN=%d\n", + serving_cell->phy_cell.id, serving_cell->get_earfcn()); + phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); + state = RRC_STATE_CELL_SELECTING; + return true; + } } } - rrc_log->info("No more known cells. Starting again\n"); + return false; } void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int pci_i) { + pthread_mutex_lock(&mutex); + if (earfcn_i < 0 || pci_i < 0) { earfcn_i = serving_cell->get_earfcn(); pci_i = serving_cell->phy_cell.id; @@ -582,16 +584,22 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p } } - // Verify cell selection criteria with strongest neighbour cell (always first) - if (neighbour_cells.size() > 1 && - cell_selection_eval(neighbour_cells[0]->get_rsrp()) && - neighbour_cells[0]->get_rsrp() > serving_cell->get_rsrp() + 5) - { - set_serving_cell(0); - rrc_log->info("Selecting best neighbour cell PCI=%d, rsrp=%.1f dBm\n", serving_cell->phy_cell.id, serving_cell->get_rsrp()); - state = RRC_STATE_CELL_SELECTING; - phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); - } + // Evaluate if we need to select a new cell + select_next_cell_in_plmn(); + } + pthread_mutex_unlock(&mutex); +} + +// PHY indicates that has gone through all known EARFCN +void rrc::earfcn_end() { + rrc_log->info("Finished searching cells in EARFCN set while in state %s\n", rrc_state_text[state]); + + // If searching for PLMN, indicate NAS we scanned all frequencies + if (state == RRC_STATE_PLMN_SELECTION) { + nas->plmn_search_end(); + } else { + rrc_log->info("Restarting Cell search...\n"); + phy->cell_search_start(); } } @@ -600,51 +608,53 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p * new cell as current serving cell */ void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { - bool found = false; - int cell_idx = -1; - + int cell_idx = -1; + bool found = true; + + pthread_mutex_lock(&mutex); + if (serving_cell->equals(earfcn, phy_cell.id)) { serving_cell->set_rsrp(rsrp); - found = true; } else { // Check if cell is in our list of neighbour cells cell_idx = find_neighbour_cell(earfcn, phy_cell.id); if (cell_idx >= 0) { set_serving_cell(cell_idx); serving_cell->set_rsrp(rsrp); - found = true; + } else { + found = false; + if (!add_neighbour_cell(earfcn, phy_cell, rsrp)) { + rrc_log->info( + "No more space for neighbour cells (detected cell RSRP=%.1f dBm worse than current %d neighbours)\n", + rsrp, + NOF_NEIGHBOUR_CELLS); + } else { + set_serving_cell(earfcn, phy_cell.id); + serving_cell->set_rsrp(rsrp); + } } } - if (found) { - if (!serving_cell->has_sib1()) { - si_acquire_state = SI_ACQUIRE_SIB1; - } else if (state == RRC_STATE_PLMN_SELECTION) { - for (uint32_t j = 0; j < serving_cell->sib1ptr()->N_plmn_ids; j++) { - nas->plmn_found(serving_cell->sib1ptr()->plmn_id[j].id, serving_cell->sib1ptr()->tracking_area_code); - } - usleep(5000); - phy->cell_search_next(); + pthread_mutex_unlock(&mutex); + + if (!serving_cell->has_sib1()) { + si_acquire_state = SI_ACQUIRE_SIB1; + } else if (state == RRC_STATE_PLMN_SELECTION) { + bool ret = false; + for (uint32_t j = 0; j < serving_cell->sib1ptr()->N_plmn_ids; j++) { + ret |= nas->plmn_found(serving_cell->sib1ptr()->plmn_id[j].id, serving_cell->sib1ptr()->tracking_area_code); } - } else { - // add to list of known cells and set current_cell - if (!add_neighbour_cell(earfcn, phy_cell, rsrp)) { - rrc_log->info("No more space for neighbour cells (detected cell RSRP=%.1f dBm worse than current %d neighbours)\n", - rsrp, NOF_NEIGHBOUR_CELLS); - usleep(5000); + // If any of the PLMNs in this cell is selected, search next cell + if (!ret) { phy->cell_search_next(); - } else { - set_serving_cell(earfcn, phy_cell.id); - si_acquire_state = SI_ACQUIRE_SIB1; } } rrc_log->info("%s %s cell EARFCN=%d, PCI=%d, RSRP=%.1f dBm\n", found?"Updating":"Adding", - cell_idx>=0?"neighbour":"serving", - serving_cell->get_earfcn(), - serving_cell->phy_cell.id, - serving_cell->get_rsrp()); + cell_idx>=0?"neighbour":"serving", earfcn, phy_cell.id, rsrp); + + } bool sort_rsrp(cell_t *u1, cell_t *u2) { @@ -668,6 +678,8 @@ void rrc::clean_neighbours() struct timeval now; gettimeofday(&now, NULL); + pthread_mutex_lock(&mutex); + std::vector::iterator it = neighbour_cells.begin(); while(it != neighbour_cells.end()) { if ((*it)->timeout_secs(now) > NEIGHBOUR_TIMEOUT) { @@ -677,6 +689,7 @@ void rrc::clean_neighbours() ++it; } } + pthread_mutex_unlock(&mutex); } // Sort neighbour cells by decreasing order of RSRP @@ -695,13 +708,17 @@ void rrc::sort_neighbour_cells() std::sort(neighbour_cells.begin(), neighbour_cells.end(), sort_rsrp); - char ordered[512]; - int n=0; - n += snprintf(ordered, 512, "[pci=%d, rsrsp=%.2f", neighbour_cells[0]->phy_cell.id, neighbour_cells[0]->get_rsrp()); - for (uint32_t i=1;iget_pci(), neighbour_cells[i]->get_rsrp()); + if (neighbour_cells.size() > 0) { + char ordered[512]; + int n=0; + n += snprintf(ordered, 512, "[pci=%d, rsrsp=%.2f", neighbour_cells[0]->phy_cell.id, neighbour_cells[0]->get_rsrp()); + for (uint32_t i=1;iget_pci(), neighbour_cells[i]->get_rsrp()); + } + rrc_log->info("Neighbours: %s]\n", ordered); + } else { + rrc_log->info("Neighbours: Empty\n"); } - rrc_log->info("Neighbours: %s]\n", ordered); } bool rrc::add_neighbour_cell(cell_t *new_cell) { @@ -744,7 +761,7 @@ bool rrc::add_neighbour_cell(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp if (cell_idx >= 0) { neighbour_cells[cell_idx]->set_rsrp(rsrp); sort_neighbour_cells(); - return true; + return true; } // If not, create a new one @@ -762,18 +779,6 @@ int rrc::find_neighbour_cell(uint32_t earfcn, uint32_t pci) { return -1; } -// PHY indicates that has gone through all known EARFCN -void rrc::earfcn_end() { - rrc_log->info("Finished searching cells in EARFCN set while in state %s\n", rrc_state_text[state]); - - // If searching for PLMN, indicate NAS we scanned all frequencies - if (state >= RRC_STATE_PLMN_SELECTION && state < RRC_STATE_CONNECTING) { - nas->plmn_search_end(); - } else if (state >= RRC_STATE_CONNECTING && state < RRC_STATE_LEAVE_CONNECTED) { - leave_connected(); - } -} - // Cell reselection in IDLE Section 5.2.4 of 36.304 void rrc::cell_reselection_eval(float rsrp, float rsrq) { @@ -826,7 +831,6 @@ float rrc::get_squal(float Qqualmeas) { // Detection of physical layer problems in RRC_CONNECTED (5.3.11.1) void rrc::out_of_sync() { - serving_cell->in_sync = false; if (state == RRC_STATE_CONNECTED) { if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) { n310_cnt++; @@ -838,9 +842,23 @@ void rrc::out_of_sync() { n310_cnt = 0; } } - } else { - phy->sync_reset(); + } else if (state != RRC_STATE_LEAVE_CONNECTED) { + if (!mac_timers->timer_get(t311)->is_running()) { + if (serving_cell->in_sync) { + rrc_log->info("Detected out-of-sync while in IDLE. Resetting sync\n"); + phy->sync_reset(); + } else { + rrc_log->info("Detected out-of-sync while in IDLE. Selecting another cell in the PLMN\n"); + if (!select_next_cell_in_plmn()) { + rrc_log->info("Could not find any available cell in this PLMN. Searching PLMN again.\n"); + plmn_search(); + } + } + } else { + rrc_log->info("Detected out-of-sync while T311 is running\n"); + } } + serving_cell->in_sync = false; } // Recovery of physical layer problems (5.3.11.2) diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index 4f4ffb687..5a4a082ba 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -81,7 +81,7 @@ public: uint32_t get_last_sdu_len() { return last_sdu_len; } void plmn_search() {}; - void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) {}; + void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, bool con_req) {}; uint16_t get_mcc() { return mcc; } uint16_t get_mnc() { return mnc; } From ac194ae7b170d98c0a5d622cdff97d1b5c5709ed Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 22:24:07 +0100 Subject: [PATCH 218/342] fix warning in timeout test --- lib/test/common/timeout_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test/common/timeout_test.cc b/lib/test/common/timeout_test.cc index c2451cdb0..4bde95f66 100644 --- a/lib/test/common/timeout_test.cc +++ b/lib/test/common/timeout_test.cc @@ -89,7 +89,7 @@ int timer_thread_test() printf("Target duration: %dms, started: %ld:%ld, ended: %ld:%ld, actual duration %dms\n", duration_msec, c.start_time[1].tv_sec, c.start_time[1].tv_usec, c.start_time[2].tv_sec, c.start_time[2].tv_usec, diff_ms); - result = (duration_msec - result_tolerance <= diff_ms < duration_msec + result_tolerance); + result = ((duration_msec - result_tolerance) < diff_ms || diff_ms < (duration_msec + result_tolerance)); if(result) { printf("Timer thread test passed\n"); From ac0f9345582539cfe14f3cd2601c9f055135962d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 22:33:57 +0100 Subject: [PATCH 219/342] fix leaks in viterbi and modem tests --- lib/src/phy/fec/test/viterbi_test.c | 1 + lib/src/phy/modem/test/modem_test.c | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/src/phy/fec/test/viterbi_test.c b/lib/src/phy/fec/test/viterbi_test.c index 28c60bce6..e4cf6f312 100644 --- a/lib/src/phy/fec/test/viterbi_test.c +++ b/lib/src/phy/fec/test/viterbi_test.c @@ -279,6 +279,7 @@ int main(int argc, char **argv) { free(llr); free(llr_c); free(data_rx); + free(data_rx2); if (snr_points == 1) { int expected_errors = get_expected_errors(nof_frames, seed, frame_length, tail_biting, ebno_db); diff --git a/lib/src/phy/modem/test/modem_test.c b/lib/src/phy/modem/test/modem_test.c index 600115386..ed9bef522 100644 --- a/lib/src/phy/modem/test/modem_test.c +++ b/lib/src/phy/modem/test/modem_test.c @@ -197,6 +197,7 @@ int main(int argc, char **argv) { } } + free(llr2); free(llr); free(symbols); free(symbols_bytes); From a85368cac0dd9cb50f2eb1878e4652df8ba882ae Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 7 Mar 2018 00:28:52 +0100 Subject: [PATCH 220/342] Discard duplicated TB after timeout --- srsue/hdr/mac/dl_harq.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index f4c557898..cfdfdfc5f 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -190,6 +190,9 @@ private: } private: + + const static int RESET_DUPLICATE_TIMEOUT = 8*6; + class dl_tb_process { public: dl_tb_process(void) { @@ -273,6 +276,10 @@ private: grant.last_tti = cur_grant.tti; memcpy(&cur_grant, &grant, sizeof(Tgrant)); + if (payload_buffer_ptr) { + Warning("DL PID %d: Allocating buffer already allocated\n", pid); + } + // Instruct the PHY To combine the received data and attempt to decode it if (pid == HARQ_BCCH_PID) { payload_buffer_ptr = harq_entity->demux_unit->request_buffer_bcch(cur_grant.n_bytes[tid]); @@ -294,8 +301,14 @@ private: } else { action->default_ack[tid] = true; - Warning("DL PID %d: Received duplicate TB. Discarting and retransmitting ACK (grant_tti=%d, ndi=%d, sz=%d)\n", - pid, cur_grant.tti, cur_grant.ndi[tid], cur_grant.n_bytes[tid]); + uint32_t interval = srslte_tti_interval(grant.tti, cur_grant.tti); + Warning("DL PID %d: Received duplicate TB. Discarting and retransmitting ACK (grant_tti=%d, ndi=%d, sz=%d, reset=%s)\n", + pid, cur_grant.tti, cur_grant.ndi[tid], cur_grant.n_bytes[tid], interval>RESET_DUPLICATE_TIMEOUT?"yes":"no"); + if (interval > RESET_DUPLICATE_TIMEOUT) { + pthread_mutex_unlock(&mutex); + reset(); + pthread_mutex_lock(&mutex); + } } if (pid == HARQ_BCCH_PID || harq_entity->timer_aligment_timer->is_expired()) { From c6c170e73750477eded20dd24d2704bcfe44976a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 7 Mar 2018 00:31:31 +0100 Subject: [PATCH 221/342] Do HO after correct synchronization --- srsue/hdr/upper/rrc.h | 3 +++ srsue/src/upper/rrc.cc | 28 +++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 904ae59db..8d092051a 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -311,6 +311,8 @@ private: uint16_t ho_src_rnti; cell_t ho_src_cell; + uint32_t ho_target_pci; + bool ho_syncing; phy_interface_rrc::phy_cfg_t ho_src_phy_cfg; mac_interface_rrc::mac_cfg_t ho_src_mac_cfg; bool pending_mob_reconf; @@ -542,6 +544,7 @@ private: // Helpers void ho_failed(); bool ho_prepare(); + void ho_synced(uint32_t target_pci); void rrc_connection_release(); void con_restablish_cell_reselected(); void radio_link_failure(); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 81331b2e4..935d24435 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -99,6 +99,8 @@ void rrc::init(phy_interface_rrc *phy_, state = RRC_STATE_IDLE; si_acquire_state = SI_ACQUIRE_IDLE; + ho_syncing = false; + thread_running = true; start(); @@ -611,6 +613,11 @@ void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { int cell_idx = -1; bool found = true; + if (ho_syncing && phy_cell.id == ho_target_pci) { + ho_synced(ho_target_pci); + return; + } + pthread_mutex_lock(&mutex); if (serving_cell->equals(earfcn, phy_cell.id)) { @@ -1127,7 +1134,9 @@ bool rrc::ho_prepare() { int target_cell_idx = find_neighbour_cell(serving_cell->get_earfcn(), mob_reconf.mob_ctrl_info.target_pci); if (target_cell_idx < 0) { rrc_log->console("Received HO command to unknown PCI=%d\n", mob_reconf.mob_ctrl_info.target_pci); - rrc_log->error("Could not find target cell earfcn=%d, pci=%d\n", serving_cell->get_earfcn(), mob_reconf.mob_ctrl_info.target_pci); + rrc_log->error("Could not find target cell earfcn=%d, pci=%d\n", + serving_cell->get_earfcn(), + mob_reconf.mob_ctrl_info.target_pci); return false; } @@ -1159,12 +1168,22 @@ bool rrc::ho_prepare() { mac->set_ho_rnti(mob_reconf.mob_ctrl_info.new_ue_id, mob_reconf.mob_ctrl_info.target_pci); apply_rr_config_common_dl(&mob_reconf.mob_ctrl_info.rr_cnfg_common); + ho_target_pci = neighbour_cells[target_cell_idx]->phy_cell.id; + ho_syncing = true; + rrc_log->info("Selecting new cell pci=%d\n", neighbour_cells[target_cell_idx]->get_pci()); if (!phy->cell_handover(neighbour_cells[target_cell_idx]->phy_cell)) { rrc_log->error("Could not synchronize with target cell pci=%d\n", neighbour_cells[target_cell_idx]->get_pci()); return false; } + } + return true; +} +void rrc::ho_synced(uint32_t current_pci) +{ + ho_syncing = false; + if (current_pci == ho_target_pci) { if (mob_reconf.mob_ctrl_info.rach_cnfg_ded_present) { rrc_log->info("Starting non-contention based RA with preamble_idx=%d, mask_idx=%d\n", mob_reconf.mob_ctrl_info.rach_cnfg_ded.preamble_index, @@ -1181,7 +1200,7 @@ bool rrc::ho_prepare() { ncc = mob_reconf.sec_cnfg_ho.intra_lte.next_hop_chaining_count; if (mob_reconf.sec_cnfg_ho.intra_lte.key_change_ind) { rrc_log->console("keyChangeIndicator in securityConfigHO not supported\n"); - return false; + return; } if (mob_reconf.sec_cnfg_ho.intra_lte.sec_alg_cnfg_present) { cipher_algo = (CIPHERING_ALGORITHM_ID_ENUM) mob_reconf.sec_cnfg_ho.intra_lte.sec_alg_cnfg.cipher_alg; @@ -1198,8 +1217,11 @@ bool rrc::ho_prepare() { pdcp->config_security_all(k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); send_rrc_con_reconfig_complete(); + } else { + rrc_log->error("HO: Synchronized with incorrect cell. Target PCI=%d, current PCI=%d\n", ho_target_pci, current_pci); + ho_failed(); } - return true; + return; } void rrc::ho_ra_completed(bool ra_successful) { From bdf379ee1c24ca8c68f0fb922b1d428e4032fb71 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 7 Mar 2018 10:50:10 +0100 Subject: [PATCH 222/342] Fixed roaming PLMN attach. Add out-of-sync debugging --- srsue/src/phy/phch_recv.cc | 2 ++ srsue/src/upper/rrc.cc | 21 +++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index ca6a35772..be483b0e4 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -717,8 +717,10 @@ void phch_recv::in_sync() { // Out of sync called by worker or phch_recv every 1 or 5 ms void phch_recv::out_of_sync() { // Send RRC out-of-sync signal after 200 ms consecutive subframes + Info("Out-of-sync %d/%d\n", out_of_sync_cnt, NOF_OUT_OF_SYNC_SF); out_of_sync_cnt++; if (out_of_sync_cnt >= NOF_OUT_OF_SYNC_SF) { + Info("Sending to RRC\n"); rrc->out_of_sync(); out_of_sync_cnt = 0; in_sync_cnt = 0; diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 935d24435..a08297da6 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -452,8 +452,12 @@ void rrc::plmn_select_rrc(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { selected_plmn_id = plmn_id; if (serving_cell->plmn_equals(selected_plmn_id) && serving_cell->in_sync) { - rrc_log->info("PLMN Id=%s selected, Selecting serving cell earfcn=%d, pci=%d\n", - plmn_id_to_string(plmn_id).c_str(), serving_cell->get_earfcn(), serving_cell->phy_cell.id); + rrc_log->info("PLMN Id=%s selected, Selecting serving cell earfcn=%d, pci=%d, status=%d\n", + plmn_id_to_string(plmn_id).c_str(), serving_cell->get_earfcn(), serving_cell->phy_cell.id, + phy->sync_status()); + if (!phy->sync_status()) { + phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); + } } else { bool found = false; for (uint32_t i=0;iinfo("Received out-of-sync state %s. n310=%d, t311=%s, t310=%s\n", + rrc_state_text[state], n310_cnt, + mac_timers->timer_get(t311)->is_running()?"running":"stop", + mac_timers->timer_get(t310)->is_running()?"running":"stop"); if (state == RRC_STATE_CONNECTED) { if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) { n310_cnt++; @@ -1168,14 +1176,15 @@ bool rrc::ho_prepare() { mac->set_ho_rnti(mob_reconf.mob_ctrl_info.new_ue_id, mob_reconf.mob_ctrl_info.target_pci); apply_rr_config_common_dl(&mob_reconf.mob_ctrl_info.rr_cnfg_common); - ho_target_pci = neighbour_cells[target_cell_idx]->phy_cell.id; - ho_syncing = true; - rrc_log->info("Selecting new cell pci=%d\n", neighbour_cells[target_cell_idx]->get_pci()); if (!phy->cell_handover(neighbour_cells[target_cell_idx]->phy_cell)) { - rrc_log->error("Could not synchronize with target cell pci=%d\n", neighbour_cells[target_cell_idx]->get_pci()); + rrc_log->error("Could not synchronize with target cell pci=%d. Trying to return to source PCI\n", + neighbour_cells[target_cell_idx]->get_pci()); + ho_failed(); return false; } + ho_target_pci = neighbour_cells[target_cell_idx]->phy_cell.id; + ho_syncing = true; } return true; } From e9213f807dd270232645402bc79a1a33bef8f767 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 7 Mar 2018 12:17:49 +0000 Subject: [PATCH 223/342] Starting to change SPGW to handle release access bearers request. Changing MME GTPC entity to contain an IMSI to sgw_ctr_fteid and ctr_teid to IMSI maps. --- srsepc/hdr/mme/mme_gtpc.h | 3 ++- srsepc/hdr/mme/s1ap_common.h | 4 ++-- srsepc/src/mme/mme_gtpc.cc | 27 +++++++++++++++++++++++++++ srsepc/src/mme/s1ap_nas_transport.cc | 2 +- 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index 8909e89e2..c1656afaf 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -68,7 +68,8 @@ private: in_addr_t m_mme_gtpc_ip; uint32_t m_next_ctrl_teid; - std::map m_teid_to_mme_s1ap_id; + std::map m_ctr_teid_to_imsi; + std::map m_imsi_to_ctr_fteid; }; diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index 1b5b0ea54..15f4e3c6d 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -127,7 +127,6 @@ typedef struct{ enum erab_state state; uint8_t erab_id; srslte::gtpc_f_teid_ie enb_fteid; - srslte::gtpc_f_teid_ie sgw_ctrl_fteid; srslte::gtpc_f_teid_ie sgw_s1u_fteid; srslte::gtpc_pdn_address_allocation_ie pdn_addr_alloc; } erab_ctx_t; @@ -148,8 +147,9 @@ typedef struct{ uint32_t mme_ue_s1ap_id; struct sctp_sndrcvinfo enb_sri; ecm_state_t ecm_state; + srslte::gtpc_f_teid_ie sgw_ctrl_fteid; + erab_ctx_t erabs_ctx[MAX_ERABS_PER_UE]; bool eit; - erab_ctx_t erabs_ctx[MAX_ERABS_PER_UE]; } ue_ecm_ctx_t; diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 70769c9ef..19bb0f96d 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -298,4 +298,31 @@ mme_gtpc::send_delete_session_request(ue_ecm_ctx_t *ue_ecm_ctx) //TODO Handle delete session response return; } + +void +mme_gtpc::send_release_access_bearers_request(ue_ecm_ctx_t *ecm_ctx) +{ + m_mme_gtpc_log->info("Sending GTP-C Delete Access Bearers Request\n"); + srslte::gtpc_pdu rel_req_pdu; + if(ecm_ctx->state != ECM_ ) + { + + } + srslte::gtpc_f_teid_ie *sgw_ctrl_fteid = NULL; + + srslte::gtpc_header *header = &rel_req_pdu.header; + header->teid_present = true; + header->teid = sgw_ctrl_fteid->teid; + header->type = srslte::GTPC_MSG_TYPE_RELEASE_ACCESS_BEARERS_REQUEST; + + srslte::gtpc_release_access_bearers_request *rel_req = &rel_req_pdu.choice.release_access_bearers_request; + del_req->cause.cause_value = srslte::GTPC_CAUSE_VALUE_ISR_DEACTIVATION; + m_mme_gtpc_log->info("GTP-C Release Access Berarers Request -- S-GW Control TEID %d\n", sgw_ctrl_fteid->teid ); + + srslte::gtpc_pdu del_resp_pdu; + m_spgw->handle_delete_session_request(&del_req_pdu, &del_resp_pdu); + + //TODO Handle delete session response + return; +} } //namespace srsepc diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index e49c3a05e..97f6149f6 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -707,7 +707,7 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",ue_emm_ctx->security_ctxt.ul_nas_count); //FIXME Send Modify context request OR send ctx release command and wait for the reply. m_mme_gtpc->send_create_session_request(ue_ecm_ctx.imsi, ue_ecm_ctx.mme_ue_s1ap_id,false); - m_s1ap_log->console("UE ESM Ctr TEID %d\n", ue_ecm_ctx.erabs_ctx[5].sgw_ctrl_fteid.teid); + m_s1ap_log->console("UE ESM Ctr TEID %d\n", ue_ecm_ctx.sgw_ctrl_fteid.teid); // m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ue_); } } From ac95976a6bbc9edf724efde39f4f74317d9ef16b Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 7 Mar 2018 14:50:56 +0100 Subject: [PATCH 224/342] Check Cell is valid before HO. Do cell search if going back to source fails --- srsue/src/phy/phch_recv.cc | 8 +++++++- srsue/src/upper/rrc.cc | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index be483b0e4..4d4dbb78e 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -220,7 +220,7 @@ bool phch_recv::set_cell() { // Set cell in all objects if (srslte_ue_sync_set_cell(&ue_sync, cell)) { - Error("SYNC: Setting cell: initiating ue_sync"); + Error("SYNC: Setting cell: initiating ue_sync\n"); return false; } measure_p.set_cell(cell); @@ -308,6 +308,12 @@ void phch_recv::cell_search_start() { bool phch_recv::cell_handover(srslte_cell_t cell) { + + if (srslte_cell_isvalid(&cell)) { + log_h->error("Received HO command to invalid cell. ID=%d, PRB=%d, ports=%d\n", cell.id, cell.nof_prb, cell.nof_ports); + return false; + } + int cnt = 0; while(worker_com->is_any_pending_ack() && cnt < 10) { usleep(1000); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index a08297da6..fdd461ebb 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1268,7 +1268,8 @@ void rrc::ho_failed() { // Instruct PHY to resync with source PCI if (!phy->cell_handover(ho_src_cell.phy_cell)) { - rrc_log->error("Could not synchronize with target cell pci=%d\n", ho_src_cell.get_pci()); + rrc_log->error("Could not synchronize with target cell pci=%d. Going to PLMN Search\n", ho_src_cell.get_pci()); + plmn_search(); return; } From 04f6634b4908434e8cc87e4e72e4a5bbacf6abc5 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 7 Mar 2018 15:02:07 +0100 Subject: [PATCH 225/342] fix condition check in cell HO --- srsue/src/phy/phch_recv.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 4d4dbb78e..112cd03b8 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -308,8 +308,7 @@ void phch_recv::cell_search_start() { bool phch_recv::cell_handover(srslte_cell_t cell) { - - if (srslte_cell_isvalid(&cell)) { + if (!srslte_cell_isvalid(&cell)) { log_h->error("Received HO command to invalid cell. ID=%d, PRB=%d, ports=%d\n", cell.id, cell.nof_prb, cell.nof_ports); return false; } From e499fffe01aaaaa51d8ef4081c01c5e0a823e668 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 7 Mar 2018 14:58:08 +0000 Subject: [PATCH 226/342] Starting to save GTP-C context in a map, to keep the GTP-C connection even when the NAS connection is released. --- lib/include/srslte/asn1/gtpc_ies.h | 5 ++-- srsepc/hdr/mme/mme_gtpc.h | 6 +++- srsepc/src/mme/mme_gtpc.cc | 41 ++++++++++++++++++++-------- srsepc/src/mme/s1ap_nas_transport.cc | 8 +++--- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/lib/include/srslte/asn1/gtpc_ies.h b/lib/include/srslte/asn1/gtpc_ies.h index 35b5e6498..657fc7c16 100644 --- a/lib/include/srslte/asn1/gtpc_ies.h +++ b/lib/include/srslte/asn1/gtpc_ies.h @@ -400,7 +400,8 @@ enum gtpc_interface_type S2B_U_PGW_GTP_U_INTERFACE }; -struct gtpc_f_teid_ie + +typedef struct gtpc_f_teid_ie { bool ipv4_present; bool ipv6_present; @@ -408,7 +409,7 @@ struct gtpc_f_teid_ie uint32_t teid; in_addr_t ipv4; struct in6_addr ipv6; //FIXME -}; +} gtp_fteid_t; //TODO //TODO IEs between 8.22 and 8.28 missing diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index c1656afaf..992ccdae7 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -42,13 +42,17 @@ class mme_gtpc { public: + struct gtpc_ctx{ + srslte::gtp_fteid_t mme_ctr_fteid; + srslte::gtp_fteid_t sgw_ctr_fteid; + }; static mme_gtpc* get_instance(void); static void cleanup(void); bool init(srslte::log_filter *mme_gtpc_log); uint32_t get_new_ctrl_teid(); - void send_create_session_request(uint64_t imsi, uint32_t mme_s1ap_id, bool pack_attach); + void send_create_session_request(uint64_t imsi, bool pack_attach); void handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pack_attach); void send_modify_bearer_request(erab_ctx_t *bearer_ctx); void handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu); diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 19bb0f96d..3e35844b2 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -88,7 +88,7 @@ mme_gtpc::get_new_ctrl_teid() return m_next_ctrl_teid++; //FIXME Use a Id pool? } void -mme_gtpc::send_create_session_request(uint64_t imsi, uint32_t mme_ue_s1ap_id, bool pack_attach) +mme_gtpc::send_create_session_request(uint64_t imsi, bool pack_attach) { m_mme_gtpc_log->info("Sending Create Session Request.\n"); m_mme_gtpc_log->console("Sending Create Session Request.\n"); @@ -96,7 +96,6 @@ mme_gtpc::send_create_session_request(uint64_t imsi, uint32_t mme_ue_s1ap_id, bo struct srslte::gtpc_create_session_request *cs_req = &cs_req_pdu.choice.create_session_request; struct srslte::gtpc_pdu cs_resp_pdu; - //Initialize GTP-C message to zero bzero(&cs_req_pdu, sizeof(struct srslte::gtpc_pdu)); @@ -113,19 +112,39 @@ mme_gtpc::send_create_session_request(uint64_t imsi, uint32_t mme_ue_s1ap_id, bo cs_req->sender_f_teid.teid = get_new_ctrl_teid(); cs_req->sender_f_teid.ipv4 = m_mme_gtpc_ip; - m_mme_gtpc_log->info("Next control TEID: %lu \n", m_next_ctrl_teid); - m_mme_gtpc_log->info("Allocated control TEID: %lu \n", cs_req->sender_f_teid.teid); + m_mme_gtpc_log->info("Next MME control TEID: %lu \n", m_next_ctrl_teid); + m_mme_gtpc_log->info("Allocated MME control TEID: %lu \n", cs_req->sender_f_teid.teid); m_mme_gtpc_log->console("Creating Session Response -- IMSI: %015lu \n", imsi); m_mme_gtpc_log->console("Creating Session Response -- MME control TEID: %lu \n", cs_req->sender_f_teid.teid); + // APN strncpy(cs_req->apn, m_s1ap->m_s1ap_args.mme_apn.c_str(), sizeof(cs_req->apn)-1); cs_req->apn[sizeof(cs_req->apn)-1] = 0; // RAT Type //cs_req->rat_type = srslte::GTPC_RAT_TYPE::EUTRAN; - //Save RX Control TEID - m_teid_to_mme_s1ap_id.insert(std::pair(cs_req->sender_f_teid.teid, mme_ue_s1ap_id)); + //Check whether this UE is already registed + std::map::iterator it = m_imsi_to_gtpc_ctx.find(imsi); + if(it == m_imsi_to_ctr_fteid.end()) + { + m_mme_gtpc_log->warning("Create Session Request being called for an UE with an active GTP-C connection.\n"); + m_mme_gtpc_log->warning("Deleting previous GTP-C connection.\n"); + std::map::iterator jt = m_mme_ctr_teid_to_imsi.find(it->second.mme_ctr_fteid.teid); + if(jt == m_ctr_teid_to_imsi.end()) + { + m_mme_gtpc_log->error("Could not find IMSI from MME Ctrl TEID.\n") + } + else + { + m_ctr_teid_to_imsi.erease(jt); + } + m_imsi_to_ctr_fteid.erease(it); + //No need to send delete session request to the SPGW. + //The create session request will be interpreted as a new request and SPGW will delete locally in existing context. + } + //Save RX Control TEID + m_mme_ctr_teid_to_imsi.insert(std::pair(cs_req->sender_f_teid.teid, imsi)); m_spgw->handle_create_session_request(cs_req, &cs_resp_pdu, pack_attach); } @@ -190,14 +209,12 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pac //Save create session response info to E-RAB context ue_ecm_ctx_t *ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_s1ap_id); - if(ecm_ctx ==NULL) - { + if(ecm_ctx ==NULL){ m_mme_gtpc_log->error("Could not find UE ECM context\n"); return; } ue_emm_ctx_t *emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ecm_ctx->imsi); - if(emm_ctx ==NULL) - { + if(emm_ctx ==NULL){ m_mme_gtpc_log->error("Could not find UE EMM context\n"); return; } @@ -304,9 +321,9 @@ mme_gtpc::send_release_access_bearers_request(ue_ecm_ctx_t *ecm_ctx) { m_mme_gtpc_log->info("Sending GTP-C Delete Access Bearers Request\n"); srslte::gtpc_pdu rel_req_pdu; - if(ecm_ctx->state != ECM_ ) + if(ecm_ctx->state != ECM_STATE_CONNECTED ) { - + m_mme_gtpc_log->error("ECM State is not connected. No valid SGW Ctr TEID present\n"); } srslte::gtpc_f_teid_ie *sgw_ctrl_fteid = NULL; diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 97f6149f6..d897d3b2e 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -592,7 +592,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); //Create session request m_s1ap_log->console("GUTI Attach -- NAS Integrity OK."); - m_mme_gtpc->send_create_session_request(ue_emm_ctx->imsi, ue_emm_ctx->mme_ue_s1ap_id,true); + m_mme_gtpc->send_create_session_request(ue_emm_ctx->imsi,true); *reply_flag = false; //No reply needed return true; } @@ -706,7 +706,7 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, liblte_security_generate_k_enb(ue_emm_ctx->security_ctxt.k_asme, ue_emm_ctx->security_ctxt.ul_nas_count, ue_emm_ctx->security_ctxt.k_enb); m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",ue_emm_ctx->security_ctxt.ul_nas_count); //FIXME Send Modify context request OR send ctx release command and wait for the reply. - m_mme_gtpc->send_create_session_request(ue_ecm_ctx.imsi, ue_ecm_ctx.mme_ue_s1ap_id,false); + m_mme_gtpc->send_create_session_request(ue_ecm_ctx.imsi,false); m_s1ap_log->console("UE ESM Ctr TEID %d\n", ue_ecm_ctx.sgw_ctrl_fteid.teid); // m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ue_); } @@ -823,7 +823,7 @@ s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas { //FIXME The packging of GTP-C messages is not ready. //This means that GTP-U tunnels are created with function calls, as opposed to GTP-C. - m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi, ue_ecm_ctx->mme_ue_s1ap_id,true); + m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi,true); *reply_flag = false; //No reply needed } return true; @@ -897,7 +897,7 @@ s1ap_nas_transport::handle_esm_information_response(srslte::byte_buffer_t *nas_m //FIXME The packging of GTP-C messages is not ready. //This means that GTP-U tunnels are created with function calls, as opposed to GTP-C. - m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi, ue_ecm_ctx->mme_ue_s1ap_id,true); + m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi,true); return true; } From 4af78e4960854909d82774fca42640d56158c4ba Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 7 Mar 2018 16:23:05 +0100 Subject: [PATCH 227/342] Fix invalid cell search check in previous commit --- srsue/src/phy/phch_recv.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 4d4dbb78e..b7bc26a86 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -309,7 +309,7 @@ void phch_recv::cell_search_start() { bool phch_recv::cell_handover(srslte_cell_t cell) { - if (srslte_cell_isvalid(&cell)) { + if (!srslte_cell_isvalid(&cell)) { log_h->error("Received HO command to invalid cell. ID=%d, PRB=%d, ports=%d\n", cell.id, cell.nof_prb, cell.nof_ports); return false; } From 0c50ccef1c9cf7067fe0ae38d9912aaa023d0daf Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 7 Mar 2018 15:36:08 +0000 Subject: [PATCH 228/342] Changed create session request to keep GTPC context. --- srsepc/hdr/mme/mme_gtpc.h | 4 ++-- srsepc/src/mme/mme_gtpc.cc | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index 992ccdae7..3c5fa27bf 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -72,8 +72,8 @@ private: in_addr_t m_mme_gtpc_ip; uint32_t m_next_ctrl_teid; - std::map m_ctr_teid_to_imsi; - std::map m_imsi_to_ctr_fteid; + std::map m_mme_ctr_teid_to_imsi; + std::map m_imsi_to_gtpc_ctx; }; diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 3e35844b2..41f025083 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -124,21 +124,21 @@ mme_gtpc::send_create_session_request(uint64_t imsi, bool pack_attach) //cs_req->rat_type = srslte::GTPC_RAT_TYPE::EUTRAN; //Check whether this UE is already registed - std::map::iterator it = m_imsi_to_gtpc_ctx.find(imsi); - if(it == m_imsi_to_ctr_fteid.end()) + std::map::iterator it = m_imsi_to_gtpc_ctx.find(imsi); + if(it == m_imsi_to_gtpc_ctx.end()) { m_mme_gtpc_log->warning("Create Session Request being called for an UE with an active GTP-C connection.\n"); m_mme_gtpc_log->warning("Deleting previous GTP-C connection.\n"); std::map::iterator jt = m_mme_ctr_teid_to_imsi.find(it->second.mme_ctr_fteid.teid); - if(jt == m_ctr_teid_to_imsi.end()) + if(jt == m_mme_ctr_teid_to_imsi.end()) { - m_mme_gtpc_log->error("Could not find IMSI from MME Ctrl TEID.\n") + m_mme_gtpc_log->error("Could not find IMSI from MME Ctrl TEID. MME Ctr TEID: %d\n", it->second.mme_ctr_fteid.teid); } else { - m_ctr_teid_to_imsi.erease(jt); + m_mme_ctr_teid_to_imsi.erase(jt); } - m_imsi_to_ctr_fteid.erease(it); + m_imsi_to_gtpc_ctx.erase(it); //No need to send delete session request to the SPGW. //The create session request will be interpreted as a new request and SPGW will delete locally in existing context. } From 98345ed6a26d290d289593ab2402a3d9fc474941 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 7 Mar 2018 18:10:58 +0000 Subject: [PATCH 229/342] Adapting send modify bearer request to new GTP-C context --- srsepc/hdr/mme/mme_gtpc.h | 6 +-- srsepc/src/mme/mme_gtpc.cc | 75 +++++++++++++++++---------- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 2 +- srsepc/src/mme/s1ap_nas_transport.cc | 2 +- 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index 3c5fa27bf..f94b05ccd 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -42,10 +42,10 @@ class mme_gtpc { public: - struct gtpc_ctx{ + typedef struct gtpc_ctx{ srslte::gtp_fteid_t mme_ctr_fteid; srslte::gtp_fteid_t sgw_ctr_fteid; - }; + }gtpc_ctx_t; static mme_gtpc* get_instance(void); static void cleanup(void); @@ -54,7 +54,7 @@ public: uint32_t get_new_ctrl_teid(); void send_create_session_request(uint64_t imsi, bool pack_attach); void handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pack_attach); - void send_modify_bearer_request(erab_ctx_t *bearer_ctx); + void send_modify_bearer_request(uint64_t imsi, erab_ctx_t *bearer_ctx); void handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu); void send_delete_session_request(ue_ecm_ctx_t *ue_ecm_ctx); diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 41f025083..fff721978 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -145,8 +145,14 @@ mme_gtpc::send_create_session_request(uint64_t imsi, bool pack_attach) //Save RX Control TEID m_mme_ctr_teid_to_imsi.insert(std::pair(cs_req->sender_f_teid.teid, imsi)); + + //Save GTP-C context + gtpc_ctx_t gtpc_ctx; + bzero(>pc_ctx,sizeof(gtpc_ctx_t)); + gtpc_ctx.mme_ctr_fteid = cs_req->sender_f_teid; + m_imsi_to_gtpc_ctx.insert(std::pair(imsi,gtpc_ctx)); m_spgw->handle_create_session_request(cs_req, &cs_resp_pdu, pack_attach); - + } void @@ -158,7 +164,7 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pac if (cs_resp_pdu->header.type != srslte::GTPC_MSG_TYPE_CREATE_SESSION_RESPONSE) { m_mme_gtpc_log->warning("Could not create GTPC session. Not a create session response\n"); - //TODO Handle err + //TODO Handle error return; } if (cs_resp->cause.cause_value != srslte::GTPC_CAUSE_VALUE_REQUEST_ACCEPTED){ @@ -166,30 +172,30 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pac //TODO Handle error return; } - - //Get MME_UE_S1AP_ID from the control TEID - std::map::iterator id_it = m_teid_to_mme_s1ap_id.find(cs_resp_pdu->header.teid); - if(id_it == m_teid_to_mme_s1ap_id.end()) + + //Get IMSI from the control TEID + std::map::iterator id_it = m_mme_ctr_teid_to_imsi.find(cs_resp_pdu->header.teid); + if(id_it == m_mme_ctr_teid_to_imsi.end()) { - //Could not find MME UE S1AP TEID - m_mme_gtpc_log->warning("Could not find MME UE S1AP TEID.\n"); + m_mme_gtpc_log->warning("Could not find IMSI from Ctrl TEID.\n"); return; } - uint32_t mme_s1ap_id = id_it->second; + uint64_t imsi = id_it->second; + + m_mme_gtpc_log->info("MME GTPC Ctrl TEID %d, IMSI %d\n", cs_resp_pdu->header.teid, imsi); - m_mme_gtpc_log->info("MME GTPC Ctrl TEID %d, MME UE S1AP Id %d\n", cs_resp_pdu->header.teid, mme_s1ap_id); //Get S-GW Control F-TEID - srslte::gtpc_f_teid_ie sgw_ctrl_fteid; - sgw_ctrl_fteid.teid = cs_resp_pdu->header.teid; - sgw_ctrl_fteid.ipv4 = 0; //FIXME This is not used for now. In the future it will be obtained from the socket addr_info + srslte::gtp_fteid_t sgw_ctr_fteid; + sgw_ctr_fteid.teid = cs_resp_pdu->header.teid; + sgw_ctr_fteid.ipv4 = 0; //FIXME This is not used for now. In the future it will be obtained from the socket addr_info //Get S-GW S1-u F-TEID if (cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid_present == false){ m_mme_gtpc_log->error("Did not receive SGW S1-U F-TEID in create session response\n"); return; } - m_mme_gtpc_log->console("Create Session Response -- SPGW control TEID %d\n", sgw_ctrl_fteid.teid); - m_mme_gtpc_log->info("Create Session Response -- SPGW control TEID %d\n", sgw_ctrl_fteid.teid); + m_mme_gtpc_log->console("Create Session Response -- SPGW control TEID %d\n", sgw_ctr_fteid.teid); + m_mme_gtpc_log->info("Create Session Response -- SPGW control TEID %d\n", sgw_ctr_fteid.teid); in_addr s1u_addr; s1u_addr.s_addr = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.ipv4; m_mme_gtpc_log->console("Create Session Response -- SPGW S1-U Address: %s\n", inet_ntoa(s1u_addr)); @@ -208,23 +214,33 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pac } //Save create session response info to E-RAB context - ue_ecm_ctx_t *ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_s1ap_id); - if(ecm_ctx ==NULL){ + ue_emm_ctx_t *emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(imsi); + if(emm_ctx == NULL){ + m_mme_gtpc_log->error("Could not find UE EMM context\n"); + return; + } + ue_ecm_ctx_t *ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(emm_ctx->mme_ue_s1ap_id); + if(ecm_ctx == NULL){ m_mme_gtpc_log->error("Could not find UE ECM context\n"); return; } - ue_emm_ctx_t *emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ecm_ctx->imsi); - if(emm_ctx ==NULL){ - m_mme_gtpc_log->error("Could not find UE EMM context\n"); + + //Save SGW ctrl F-TEID in GTP-C context + std::map::iterator it_g = m_imsi_to_gtpc_ctx.find(imsi); + if(it_g == m_imsi_to_gtpc_ctx.end()) + { + //Could not find GTP-C Context + m_mme_gtpc_log->error("Could not find GTP-C context\n"); return; } + gtpc_ctx_t *gtpc_ctx = &it_g->second; + gtpc_ctx->sgw_ctr_fteid = sgw_ctr_fteid; //Set EPS bearer context //FIXME default EPS bearer is hard-coded int default_bearer=5; erab_ctx_t *erab_ctx = &ecm_ctx->erabs_ctx[default_bearer]; erab_ctx->pdn_addr_alloc= cs_resp->paa; - erab_ctx->sgw_ctrl_fteid = sgw_ctrl_fteid; erab_ctx->sgw_s1u_fteid = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid; m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, erab_ctx, pack_attach); @@ -232,16 +248,23 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pac void -mme_gtpc::send_modify_bearer_request(erab_ctx_t *erab_ctx) +mme_gtpc::send_modify_bearer_request(uint64_t imsi, erab_ctx_t *erab_ctx) { m_mme_gtpc_log->info("Sending GTP-C Modify bearer request\n"); srslte::gtpc_pdu mb_req_pdu; - srslte::gtpc_f_teid_ie *enb_fteid = &erab_ctx->enb_fteid; - srslte::gtpc_f_teid_ie *sgw_ctrl_fteid = &erab_ctx->sgw_ctrl_fteid; + srslte::gtp_fteid_t *enb_fteid = &erab_ctx->enb_fteid; + + std::map::iterator it = m_imsi_to_gtpc_ctx.find(imsi); + if(it == m_imsi_to_gtpc_ctx.end()) + { + m_mme_gtpc_log->error("Modify bearer request for UE without GTP-C connection\n"); + return; + } + srslte::gtp_fteid_t sgw_ctr_fteid = it->second.sgw_ctr_fteid; srslte::gtpc_header *header = &mb_req_pdu.header; header->teid_present = true; - header->teid = sgw_ctrl_fteid->teid; + header->teid = sgw_ctr_fteid.teid; header->type = srslte::GTPC_MSG_TYPE_MODIFY_BEARER_REQUEST; srslte::gtpc_modify_bearer_request *mb_req = &mb_req_pdu.choice.modify_bearer_request; @@ -249,7 +272,7 @@ mme_gtpc::send_modify_bearer_request(erab_ctx_t *erab_ctx) mb_req->eps_bearer_context_to_modify.s1_u_enb_f_teid.ipv4 = enb_fteid->ipv4; mb_req->eps_bearer_context_to_modify.s1_u_enb_f_teid.teid = enb_fteid->teid; - m_mme_gtpc_log->info("GTP-C Modify bearer request -- S-GW Control TEID %d\n", sgw_ctrl_fteid->teid ); + m_mme_gtpc_log->info("GTP-C Modify bearer request -- S-GW Control TEID %d\n", sgw_ctr_fteid.teid ); struct in_addr addr; addr.s_addr = enb_fteid->ipv4; m_mme_gtpc_log->info("GTP-C Modify bearer request -- S1-U TEID 0x%x, IP %s\n", enb_fteid->teid, inet_ntoa(addr) ); diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 83b5c9594..02a2fb8d2 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -246,7 +246,7 @@ s1ap_ctx_mngmt_proc::handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_I } if(send_modify) { - m_mme_gtpc->send_modify_bearer_request(&ue_ecm_ctx->erabs_ctx[5]); + m_mme_gtpc->send_modify_bearer_request(ue_ecm_ctx->imsi, &ue_ecm_ctx->erabs_ctx[5]); } send_modify = true; return true; diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index d897d3b2e..11eb2b9af 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -861,7 +861,7 @@ s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, u m_s1ap_log->error("EPS Bearer ID out of range\n"); return false; } - m_mme_gtpc->send_modify_bearer_request(&ue_ecm_ctx->erabs_ctx[act_bearer.eps_bearer_id]); + m_mme_gtpc->send_modify_bearer_request(ue_ecm_ctx->imsi, &ue_ecm_ctx->erabs_ctx[act_bearer.eps_bearer_id]); //Send reply to eNB m_s1ap_log->console("Packing EMM infromationi\n"); From a3b31966b88c899e63776f886bd50d2d4320d8fd Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 7 Mar 2018 18:48:08 +0000 Subject: [PATCH 230/342] Changing Activate EPS bearer function to work with IMSI. --- srsepc/hdr/mme/s1ap.h | 2 +- srsepc/src/mme/mme_gtpc.cc | 8 ++++---- srsepc/src/mme/s1ap.cc | 22 +++++++++++++++------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 3f9f035e0..311a65784 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -72,7 +72,7 @@ public: bool handle_initiating_message(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg, struct sctp_sndrcvinfo *enb_sri); bool handle_successful_outcome(LIBLTE_S1AP_SUCCESSFULOUTCOME_STRUCT *msg); - void activate_eps_bearer(uint32_t mme_s1ap_id, uint8_t ebi); + void activate_eps_bearer(uint64_t imsi, uint8_t ebi); void print_enb_ctx_info(const std::string &prefix, const enb_ctx_t &enb_ctx); diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index fff721978..ff603e14d 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -288,16 +288,16 @@ void mme_gtpc::handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu) { uint32_t mme_ctrl_teid = mb_resp_pdu->header.teid; - std::map::iterator mme_s1ap_id_it = m_teid_to_mme_s1ap_id.find(mme_ctrl_teid); - if(mme_s1ap_id_it == m_teid_to_mme_s1ap_id.end()) + std::map::iterator imsi_it = m_mme_ctr_teid_to_imsi.find(mme_ctrl_teid); + if(imsi_it == m_mme_ctr_teid_to_imsi.end()) { - m_mme_gtpc_log->error("Could not find MME S1AP Id from control TEID\n"); + m_mme_gtpc_log->error("Could not find IMSI from control TEID\n"); return; } uint8_t ebi = mb_resp_pdu->choice.modify_bearer_response.eps_bearer_context_modified.ebi; m_mme_gtpc_log->debug("Activating EPS bearer with id %d\n", ebi); - m_s1ap->activate_eps_bearer(mme_s1ap_id_it->second,ebi); + m_s1ap->activate_eps_bearer(imsi_it->second,ebi); return; } diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 6e301b9ae..a54096114 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -501,23 +501,31 @@ s1ap::delete_ues_ecm_ctx_in_enb(uint16_t enb_id) //UE Bearer Managment void -s1ap::activate_eps_bearer(uint32_t mme_s1ap_id, uint8_t ebi) +s1ap::activate_eps_bearer(uint64_t imsi, uint8_t ebi) { - std::map::iterator ue_ctx_it = m_mme_ue_s1ap_id_to_ue_ecm_ctx.find(mme_s1ap_id); - if(ue_ctx_it == m_mme_ue_s1ap_id_to_ue_ecm_ctx.end()) + std::map::iterator emm_ctx_it = m_imsi_to_ue_emm_ctx.find(imsi); + if(emm_ctx_it == m_imsi_to_ue_emm_ctx.end()) { - m_s1ap_log->error("Could not find UE context\n"); + m_s1ap_log->error("Could not find UE EMM context\n"); + return; + } + uint32_t mme_ue_s1ap_id = emm_ctx_it->second->mme_ue_s1ap_id; + std::map::iterator ecm_ctx_it = m_mme_ue_s1ap_id_to_ue_ecm_ctx.find(mme_s1ap_id); + if(ecm_ctx_it == m_mme_ue_s1ap_id_to_ue_ecm_ctx.end()) + { + m_s1ap_log->error("Could not find UE ECM context\n"); return; } - ue_ecm_ctx_t * ue_ctx = ue_ctx_it->second; - if (ue_ctx->erabs_ctx[ebi].state != ERAB_CTX_SETUP) + + ue_ecm_ctx_t * ecm_ctx = ue_ctx_it->second; + if (ecm_ctx->erabs_ctx[ebi].state != ERAB_CTX_SETUP) { m_s1ap_log->error("EPS Bearer could not be activated. MME S1AP Id %d, EPS Bearer id %d, state %d\n",mme_s1ap_id,ebi,ue_ctx->erabs_ctx[ebi].state); m_s1ap_log->console("EPS Bearer could not be activated. MME S1AP Id %d, EPS Bearer id %d\n",mme_s1ap_id,ebi,ue_ctx->erabs_ctx[ebi].state); return; } - ue_ctx->erabs_ctx[ebi].state = ERAB_ACTIVE; + ecm_ctx->erabs_ctx[ebi].state = ERAB_ACTIVE; m_s1ap_log->info("Activated EPS Bearer\n"); return; } From ef4ad0aa20bf913a2132cb3537ed88d9698c830d Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 7 Mar 2018 19:15:32 +0000 Subject: [PATCH 231/342] Starting to change delete session request. --- srsepc/src/mme/mme_gtpc.cc | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index ff603e14d..015ce5093 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -303,25 +303,13 @@ mme_gtpc::handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu) } void -mme_gtpc::send_delete_session_request(ue_ecm_ctx_t *ue_ecm_ctx) +mme_gtpc::send_delete_session_request(uint64_t imsi) { - m_mme_gtpc_log->info("Sending GTP-C Delete Session Request request\n"); + m_mme_gtpc_log->info("Sending GTP-C Delete Session Request request. IMSI %d\n",imsi); srslte::gtpc_pdu del_req_pdu; - srslte::gtpc_f_teid_ie *sgw_ctrl_fteid = NULL; - - //FIXME the UE control TEID sould be stored in the UE ctxt, not in the E-RAB ctxt - //Maybe a mme_s1ap_id to ctrl teid map as well? + srslte::gtp_fteid_t sgw_ctrl_fteid; - for(int i = 0; ierabs_ctx[i].state != ERAB_DEACTIVATED) - { - sgw_ctrl_fteid = &ue_ecm_ctx->erabs_ctx[i].sgw_ctrl_fteid; - break; - } - } - //FIXME: add proper error handling - assert(sgw_ctrl_fteid != NULL); + std::map::iterator it = m_imsi_to_gtpc_ctx.find(imsi); srslte::gtpc_header *header = &del_req_pdu.header; header->teid_present = true; From 57e0c01fc4638acc41711ac94d0028c09b5dd99c Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 7 Mar 2018 15:27:08 +0100 Subject: [PATCH 232/342] check max buffer length in hex print --- lib/include/srslte/phy/utils/vector.h | 2 +- lib/src/phy/utils/vector.c | 9 ++++++++- srsue/src/mac/demux.cc | 2 +- srsue/src/phy/phch_worker.cc | 4 ++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/include/srslte/phy/utils/vector.h b/lib/include/srslte/phy/utils/vector.h index 4ec95639a..fbf000a70 100644 --- a/lib/include/srslte/phy/utils/vector.h +++ b/lib/include/srslte/phy/utils/vector.h @@ -73,7 +73,7 @@ SRSLTE_API void srslte_vec_fprint_byte(FILE *stream, uint8_t *x, const uint32_t SRSLTE_API void srslte_vec_fprint_i(FILE *stream, int *x, const uint32_t len); SRSLTE_API void srslte_vec_fprint_s(FILE *stream, short *x, const uint32_t len); SRSLTE_API void srslte_vec_fprint_hex(FILE *stream, uint8_t *x, const uint32_t len); -SRSLTE_API void srslte_vec_sprint_hex(char *str, uint8_t *x, const uint32_t len); +SRSLTE_API void srslte_vec_sprint_hex(char *str, const uint32_t max_str_len, uint8_t *x, const uint32_t len); /* Saves/loads a vector to a file */ SRSLTE_API void srslte_vec_save_file(char *filename, const void *buffer, const uint32_t len); diff --git a/lib/src/phy/utils/vector.c b/lib/src/phy/utils/vector.c index b97583bb8..9ccd21559 100644 --- a/lib/src/phy/utils/vector.c +++ b/lib/src/phy/utils/vector.c @@ -200,10 +200,16 @@ void srslte_vec_fprint_hex(FILE *stream, uint8_t *x, const uint32_t len) { fprintf(stream, "];\n"); } -void srslte_vec_sprint_hex(char *str, uint8_t *x, const uint32_t len) { +void srslte_vec_sprint_hex(char *str, const uint32_t max_str_len, uint8_t *x, const uint32_t len) { uint32_t i, nbytes; uint8_t byte; nbytes = len/8; + // check that hex string fits in buffer (every byte takes 3 characters, plus brackets) + if ((3*(len/8 + ((len%8)?1:0))) + 2 >= max_str_len) { + fprintf(stderr, "Buffer too small for printing hex string (max_str_len=%d, payload_len=%d).\n", max_str_len, len); + return; + } + int n=0; n+=sprintf(&str[n], "["); for (i=0;iwrite_pdu(pdu_msg->get()->get_sdu_lcid(), pdu_msg->get()->get_sdu_ptr(), pdu_msg->get()->get_payload_size()); } else { char tmp[1024]; - srslte_vec_sprint_hex(tmp, pdu_msg->get()->get_sdu_ptr(), 32); + srslte_vec_sprint_hex(tmp, sizeof(tmp), pdu_msg->get()->get_sdu_ptr(), 32); Error("PDU size %d exceeds maximum PDU buffer size, lcid=%d, hex=[%s]\n", pdu_msg->get()->get_payload_size(), pdu_msg->get()->get_sdu_lcid(), tmp); } diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 19106c514..8a6c5cd8b 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -577,7 +577,7 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) char hexstr[16]; hexstr[0]='\0'; if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { - srslte_vec_sprint_hex(hexstr, dci_msg.data, dci_msg.nof_bits); + srslte_vec_sprint_hex(hexstr, sizeof(hexstr), dci_msg.data, dci_msg.nof_bits); } Info("PDCCH: DL DCI %s cce_index=%2d, L=%d, n_data_bits=%d, hex=%s\n", srslte_dci_format_string(dci_msg.format), last_dl_pdcch_ncce, (1<get_level() >= srslte::LOG_LEVEL_INFO) { - srslte_vec_sprint_hex(hexstr, dci_msg.data, dci_msg.nof_bits); + srslte_vec_sprint_hex(hexstr, sizeof(hexstr), dci_msg.data, dci_msg.nof_bits); } // Change to last_location_ul Info("PDCCH: UL DCI Format0 cce_index=%d, L=%d, n_data_bits=%d, hex=%s\n", From 7acc021a4e4d497b43100172f9b73dc5750d63d3 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 7 Mar 2018 16:32:40 +0100 Subject: [PATCH 233/342] fix mem leak in pmch_test --- lib/src/phy/phch/test/pmch_test.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/src/phy/phch/test/pmch_test.c b/lib/src/phy/phch/test/pmch_test.c index a69b5d075..15634fe9b 100644 --- a/lib/src/phy/phch/test/pmch_test.c +++ b/lib/src/phy/phch/test/pmch_test.c @@ -157,6 +157,7 @@ int main(int argc, char **argv) { bzero(ce, sizeof(cf_t*)*SRSLTE_MAX_PORTS); bzero(tx_slot_symbols, sizeof(cf_t*)*SRSLTE_MAX_PORTS); bzero(rx_slot_symbols, sizeof(cf_t*)*SRSLTE_MAX_PORTS); + bzero(t, 3 * sizeof(struct timeval)); cell.nof_ports = 1; @@ -469,5 +470,8 @@ quit: } else { printf("Ok\n"); } + + srslte_dft_exit(); + exit(ret); } From 938e56fa2cc63eb5541b2f79b5e60e132c41a77c Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 8 Mar 2018 11:41:21 +0100 Subject: [PATCH 234/342] streamline log output in RLC AM/UM --- lib/src/upper/rlc_am.cc | 4 ++-- lib/src/upper/rlc_um.cc | 2 +- srsue/src/mac/mux.cc | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index e6e1ff279..5c7cb72ea 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -198,7 +198,7 @@ uint32_t rlc_am::get_bearer() void rlc_am::write_sdu(byte_buffer_t *sdu) { tx_sdu_queue.write(sdu); - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, tx_sdu_queue_len=%d", rrc->get_rb_name(lcid).c_str(), tx_sdu_queue.size()); + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); } /**************************************************************************** @@ -848,7 +848,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) // Set SN header.sn = vt_s; vt_s = (vt_s + 1)%MOD; - log->info("%s PDU scheduled for tx. SN: %d\n", rrc->get_rb_name(lcid).c_str(), header.sn); + log->info("%s PDU scheduled for tx. SN: %d (%d B)\n", rrc->get_rb_name(lcid).c_str(), header.sn, pdu->N_bytes); // Place PDU in tx_window, write header and TX tx_window[header.sn].buf = pdu; diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 647494552..6bbefaf78 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -173,7 +173,7 @@ uint32_t rlc_um::get_bearer() void rlc_um::write_sdu(byte_buffer_t *sdu) { tx_sdu_queue.write(sdu); - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, tx_sdu_len=%d", rrc->get_rb_name(lcid).c_str(), tx_sdu_queue.size()); + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (% B ,tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); } /**************************************************************************** diff --git a/srsue/src/mac/mux.cc b/srsue/src/mac/mux.cc index 59b94f085..33d048957 100644 --- a/srsue/src/mac/mux.cc +++ b/srsue/src/mac/mux.cc @@ -166,8 +166,7 @@ uint8_t* mux::pdu_get(uint8_t *payload, uint32_t pdu_sz, uint32_t tx_tti, uint32 } } -// Logical Channel Procedure - + // Logical Channel Procedure bool is_rar = false; pdu_msg.init_tx(payload, pdu_sz, true); @@ -325,7 +324,6 @@ bool mux::allocate_sdu(uint32_t lcid, srslte::sch_pdu* pdu_msg, int max_sdu_sz) if (pdu_msg->new_subh()) { // there is space for a new subheader sdu_len = pdu_msg->get()->set_sdu(lcid, sdu_len, rlc); if (sdu_len > 0) { // new SDU could be added - Debug("SDU: allocated lcid=%d, rlc_buffer=%d, allocated=%d/%d, max_sdu_sz=%d, remaining=%d\n", lcid, buffer_state, sdu_len, sdu_space, max_sdu_sz, pdu_msg->rem_size()); return true; From 3b338067c90dcff0841326043c5628aa3b9afd30 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 8 Mar 2018 12:13:53 +0000 Subject: [PATCH 235/342] Changing Delete session request to delete GTP-C context. --- srsepc/hdr/mme/mme_gtpc.h | 2 +- srsepc/src/mme/mme_gtpc.cc | 33 +++++++++++++++++++++------ srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 2 +- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index f94b05ccd..b832969ee 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -56,7 +56,7 @@ public: void handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pack_attach); void send_modify_bearer_request(uint64_t imsi, erab_ctx_t *bearer_ctx); void handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu); - void send_delete_session_request(ue_ecm_ctx_t *ue_ecm_ctx); + void send_delete_session_request(uint64_t imsi); private: diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 015ce5093..eec12d9ac 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -307,28 +307,47 @@ mme_gtpc::send_delete_session_request(uint64_t imsi) { m_mme_gtpc_log->info("Sending GTP-C Delete Session Request request. IMSI %d\n",imsi); srslte::gtpc_pdu del_req_pdu; - srslte::gtp_fteid_t sgw_ctrl_fteid; - - std::map::iterator it = m_imsi_to_gtpc_ctx.find(imsi); - + srslte::gtp_fteid_t sgw_ctr_fteid; + srslte::gtp_fteid_t mme_ctr_fteid; + //Get S-GW Ctr TEID + std::map::iterator it_ctx = m_imsi_to_gtpc_ctx.find(imsi); + if(it_ctx == m_imsi_to_gtpc_ctx.end()) + { + m_mme_gtpc_log->error("Could not find GTP-C context to remove\n"); + return; + } + sgw_ctr_fteid = it_ctx->second.sgw_ctr_fteid; + mme_ctr_fteid = it_ctx->second.mme_ctr_fteid; srslte::gtpc_header *header = &del_req_pdu.header; header->teid_present = true; - header->teid = sgw_ctrl_fteid->teid; + header->teid = sgw_ctr_fteid.teid; header->type = srslte::GTPC_MSG_TYPE_DELETE_SESSION_REQUEST; srslte::gtpc_delete_session_request *del_req = &del_req_pdu.choice.delete_session_request; del_req->cause.cause_value = srslte::GTPC_CAUSE_VALUE_ISR_DEACTIVATION; - m_mme_gtpc_log->info("GTP-C Delete Session Request -- S-GW Control TEID %d\n", sgw_ctrl_fteid->teid ); + m_mme_gtpc_log->info("GTP-C Delete Session Request -- S-GW Control TEID %d\n", sgw_ctr_fteid.teid ); srslte::gtpc_pdu del_resp_pdu; m_spgw->handle_delete_session_request(&del_req_pdu, &del_resp_pdu); //TODO Handle delete session response + + //Delete GTP-C context + std::map::iterator it_imsi = m_mme_ctr_teid_to_imsi.find(mme_ctr_fteid.teid); + if(it_imsi == m_mme_ctr_teid_to_imsi.end()) + { + m_mme_gtpc_log->error("Could not find IMSI from MME ctr TEID"); + } + else + { + m_mme_ctr_teid_to_imsi.erase(it_imsi); + } + m_imsi_to_gtpc_ctx.erase(it_ctx); return; } void -mme_gtpc::send_release_access_bearers_request(ue_ecm_ctx_t *ecm_ctx) +mme_gtpc::send_release_access_bearers_request(uint64_t imsi) { m_mme_gtpc_log->info("Sending GTP-C Delete Access Bearers Request\n"); srslte::gtpc_pdu rel_req_pdu; diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 02a2fb8d2..dd211cb04 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -283,7 +283,7 @@ s1ap_ctx_mngmt_proc::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECON if(active == true) { //There are active E-RABs, send delete session request - m_mme_gtpc->send_delete_session_request(ue_ecm_ctx); + m_mme_gtpc->send_delete_session_request(ue_ecm_ctx->imsi); } //m_s1ap->delete_ue_ctx(ue_ctx); for(int i=0;i Date: Thu, 8 Mar 2018 12:50:07 +0000 Subject: [PATCH 236/342] Adding release access bearers request. --- lib/include/srslte/asn1/gtpc.h | 33 +++++++++++++----------------- lib/include/srslte/asn1/gtpc_msg.h | 31 ++++++++++++++++++++++++++++ srsepc/hdr/mme/mme_gtpc.h | 1 + srsepc/src/mme/mme_gtpc.cc | 11 +++------- 4 files changed, 49 insertions(+), 27 deletions(-) diff --git a/lib/include/srslte/asn1/gtpc.h b/lib/include/srslte/asn1/gtpc.h index aca57a4bf..d204cd31d 100644 --- a/lib/include/srslte/asn1/gtpc.h +++ b/lib/include/srslte/asn1/gtpc.h @@ -52,16 +52,15 @@ const uint8_t GTPC_V2 = 2; * n+2 | Sequence | * n+3 | Spare | ***************************************************************************/ - - typedef struct gtpc_header - { - uint8_t version; - bool piggyback; - bool teid_present; - uint8_t type; - uint64_t teid; - uint64_t sequence; - } gtpc_header_t; +typedef struct gtpc_header +{ + uint8_t version; + bool piggyback; + bool teid_present; + uint8_t type; + uint64_t teid; + uint64_t sequence; +}gtpc_header_t; /**************************************************************************** * GTP-C v2 Payload @@ -69,16 +68,17 @@ const uint8_t GTPC_V2 = 2; * * Union that hold the different structures for the possible message types. ***************************************************************************/ - typedef union gtpc_msg_choice { struct gtpc_create_session_request create_session_request; struct gtpc_create_session_response create_session_response; struct gtpc_modify_bearer_request modify_bearer_request; struct gtpc_modify_bearer_response modify_bearer_response; + struct gtpc_release_access_bearers_request release_access_bearers_request; + struct gtpc_release_access_bearers_response release_access_bearers_response; struct gtpc_delete_session_request delete_session_request; struct gtpc_delete_session_response delete_session_response; -} gtpc_msg_choice_t; +}gtpc_msg_choice_t; /**************************************************************************** * GTP-C v2 Message @@ -88,15 +88,10 @@ typedef union gtpc_msg_choice * of one GTP-C header and one union of structures, which can hold * all the possible GTP-C messages ***************************************************************************/ - typedef struct gtpc_pdu { struct gtpc_header header; union gtpc_msg_choice choice; -} gtpc_pdu_t; - - - -}; - +}gtpc_pdu_t; +}//namespace #endif diff --git a/lib/include/srslte/asn1/gtpc_msg.h b/lib/include/srslte/asn1/gtpc_msg.h index 4271b064d..159be0c80 100644 --- a/lib/include/srslte/asn1/gtpc_msg.h +++ b/lib/include/srslte/asn1/gtpc_msg.h @@ -410,5 +410,36 @@ struct gtpc_delete_session_response //Private extension }; +/**************************************************************************** + * + * GTP-C v2 Release Access Bearers Request + * Ref: 3GPP TS 29.274 v10.14.0 Table 7.2.21.1-1 + * + ***************************************************************************/ +struct gtpc_release_access_bearers_request +{ + bool list_of_rabs_present; + //Linked EPS Bearer ID + bool originating_node_present; + //Indication Flags + //Private Extension +}; + + /**************************************************************************** + * + * GTP-C v2 Delete Session Response + * Ref: 3GPP TS 29.274 v10.14.0 Table 7.2.22.1-1 + * + ***************************************************************************/ + + struct gtpc_release_access_bearers_response + { + struct gtpc_cause_ie cause; + //Recovery + //Private extension + }; + + + } //namespace #endif //GTPC_V2_MSG_H diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index b832969ee..6e3ab76b1 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -56,6 +56,7 @@ public: void handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pack_attach); void send_modify_bearer_request(uint64_t imsi, erab_ctx_t *bearer_ctx); void handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu); + void send_release_access_bearers_request(uint64_t imsi); void send_delete_session_request(uint64_t imsi); private: diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index eec12d9ac..6a6ffda5c 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -351,10 +351,6 @@ mme_gtpc::send_release_access_bearers_request(uint64_t imsi) { m_mme_gtpc_log->info("Sending GTP-C Delete Access Bearers Request\n"); srslte::gtpc_pdu rel_req_pdu; - if(ecm_ctx->state != ECM_STATE_CONNECTED ) - { - m_mme_gtpc_log->error("ECM State is not connected. No valid SGW Ctr TEID present\n"); - } srslte::gtpc_f_teid_ie *sgw_ctrl_fteid = NULL; srslte::gtpc_header *header = &rel_req_pdu.header; @@ -363,13 +359,12 @@ mme_gtpc::send_release_access_bearers_request(uint64_t imsi) header->type = srslte::GTPC_MSG_TYPE_RELEASE_ACCESS_BEARERS_REQUEST; srslte::gtpc_release_access_bearers_request *rel_req = &rel_req_pdu.choice.release_access_bearers_request; - del_req->cause.cause_value = srslte::GTPC_CAUSE_VALUE_ISR_DEACTIVATION; m_mme_gtpc_log->info("GTP-C Release Access Berarers Request -- S-GW Control TEID %d\n", sgw_ctrl_fteid->teid ); - srslte::gtpc_pdu del_resp_pdu; - m_spgw->handle_delete_session_request(&del_req_pdu, &del_resp_pdu); + srslte::gtpc_pdu rel_resp_pdu; + m_spgw->handle_release_access_bearers_response(&del_req_pdu, &rel_resp_pdu); - //TODO Handle delete session response + //The GTP-C connection will not be torn down, just the user plane bearers. return; } } //namespace srsepc From a0fff683f25163b8a2c2692245cfab95cea46d68 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 8 Mar 2018 14:39:01 +0100 Subject: [PATCH 237/342] Fixed pdsch_ue; it does not stop RF after cell search. --- lib/examples/pdsch_ue.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index 74bac426d..fc99fdc9a 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -451,9 +451,6 @@ int main(int argc, char **argv) { exit(0); } - srslte_rf_stop_rx_stream(&rf); - srslte_rf_flush_buffer(&rf); - /* set sampling frequency */ int srate = srslte_sampling_freq_hz(cell.nof_prb); if (srate != -1) { From 2b84e7838978784247c6547d7e82baebb44a94ed Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 8 Mar 2018 14:19:13 +0000 Subject: [PATCH 238/342] Adding release access bearer request to SPGW. Compiling now. --- srsepc/hdr/spgw/spgw.h | 1 + srsepc/src/mme/mme_gtpc.cc | 2 +- srsepc/src/mme/s1ap.cc | 8 ++++---- srsepc/src/spgw/spgw.cc | 29 ++++++++++++++++++++++++++++- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/srsepc/hdr/spgw/spgw.h b/srsepc/hdr/spgw/spgw.h index 3837dcf08..14868c571 100644 --- a/srsepc/hdr/spgw/spgw.h +++ b/srsepc/hdr/spgw/spgw.h @@ -76,6 +76,7 @@ public: void handle_create_session_request(struct srslte::gtpc_create_session_request *cs_req, struct srslte::gtpc_pdu *cs_resp_pdu,bool pack_attach); void handle_modify_bearer_request(struct srslte::gtpc_pdu *mb_req_pdu, struct srslte::gtpc_pdu *mb_resp_pdu); void handle_delete_session_request(struct srslte::gtpc_pdu *del_req_pdu, struct srslte::gtpc_pdu *del_resp_pdu); + void handle_release_access_bearers_request(struct srslte::gtpc_pdu *rel_req_pdu, struct srslte::gtpc_pdu *rel_resp_pdu); void handle_sgi_pdu(srslte::byte_buffer_t *msg); void handle_s1u_pdu(srslte::byte_buffer_t *msg); diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 6a6ffda5c..608b29b6e 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -362,7 +362,7 @@ mme_gtpc::send_release_access_bearers_request(uint64_t imsi) m_mme_gtpc_log->info("GTP-C Release Access Berarers Request -- S-GW Control TEID %d\n", sgw_ctrl_fteid->teid ); srslte::gtpc_pdu rel_resp_pdu; - m_spgw->handle_release_access_bearers_response(&del_req_pdu, &rel_resp_pdu); + m_spgw->handle_release_access_bearers_request(&rel_req_pdu, &rel_resp_pdu); //The GTP-C connection will not be torn down, just the user plane bearers. return; diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index a54096114..19b32ba24 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -510,18 +510,18 @@ s1ap::activate_eps_bearer(uint64_t imsi, uint8_t ebi) return; } uint32_t mme_ue_s1ap_id = emm_ctx_it->second->mme_ue_s1ap_id; - std::map::iterator ecm_ctx_it = m_mme_ue_s1ap_id_to_ue_ecm_ctx.find(mme_s1ap_id); + std::map::iterator ecm_ctx_it = m_mme_ue_s1ap_id_to_ue_ecm_ctx.find(mme_ue_s1ap_id); if(ecm_ctx_it == m_mme_ue_s1ap_id_to_ue_ecm_ctx.end()) { m_s1ap_log->error("Could not find UE ECM context\n"); return; } - ue_ecm_ctx_t * ecm_ctx = ue_ctx_it->second; + ue_ecm_ctx_t * ecm_ctx = ecm_ctx_it->second; if (ecm_ctx->erabs_ctx[ebi].state != ERAB_CTX_SETUP) { - m_s1ap_log->error("EPS Bearer could not be activated. MME S1AP Id %d, EPS Bearer id %d, state %d\n",mme_s1ap_id,ebi,ue_ctx->erabs_ctx[ebi].state); - m_s1ap_log->console("EPS Bearer could not be activated. MME S1AP Id %d, EPS Bearer id %d\n",mme_s1ap_id,ebi,ue_ctx->erabs_ctx[ebi].state); + m_s1ap_log->error("EPS Bearer could not be activated. MME S1AP Id %d, EPS Bearer id %d, state %d\n",mme_ue_s1ap_id,ebi,ecm_ctx->erabs_ctx[ebi].state); + m_s1ap_log->console("EPS Bearer could not be activated. MME S1AP Id %d, EPS Bearer id %d\n",mme_ue_s1ap_id,ebi,ecm_ctx->erabs_ctx[ebi].state); return; } diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index df62fa43b..b16b89c27 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -571,7 +571,7 @@ spgw::handle_delete_session_request(struct srslte::gtpc_pdu *del_req_pdu, struct //Delete data tunnel pthread_mutex_lock(&m_mutex); - std::map::iterator data_it = m_ip_to_teid.find(tunnel_ctx->ue_ipv4); + std::map::iterator data_it = m_ip_to_teid.find(tunnel_ctx->ue_ipv4); if(data_it != m_ip_to_teid.end()) { m_ip_to_teid.erase(data_it); @@ -583,4 +583,31 @@ spgw::handle_delete_session_request(struct srslte::gtpc_pdu *del_req_pdu, struct return; } +void +spgw::handle_release_access_bearers_request(struct srslte::gtpc_pdu *rel_req_pdu, struct srslte::gtpc_pdu *rel_resp_pdu) +{ + //Find tunel ctxt + uint32_t ctrl_teid = rel_req_pdu->header.teid; + std::map::iterator tunnel_it = m_teid_to_tunnel_ctx.find(ctrl_teid); + if(tunnel_it == m_teid_to_tunnel_ctx.end()) + { + m_spgw_log->warning("Could not find TEID %d to release bearers from\n",ctrl_teid); + return; + } + spgw_tunnel_ctx_t *tunnel_ctx = tunnel_it->second; + in_addr_t ue_ipv4 = tunnel_ctx->ue_ipv4; + + //Delete data tunnel + pthread_mutex_lock(&m_mutex); + std::map::iterator data_it = m_ip_to_teid.find(tunnel_ctx->ue_ipv4); + if(data_it != m_ip_to_teid.end()) + { + m_ip_to_teid.erase(data_it); + } + pthread_mutex_unlock(&m_mutex); + + //Do NOT delete control tunnel + return; +} + } //namespace srsepc From 6583d6b2e5713eeb94fa62bbb1026bb08adb208f Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 8 Mar 2018 15:55:53 +0000 Subject: [PATCH 239/342] Changing handle UE context release to send release access bearer request instead od delte session request. --- srsepc/hdr/mme/s1ap_common.h | 2 +- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 34 ++++++++++++--------------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index 15f4e3c6d..4cda8376f 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -146,7 +146,7 @@ typedef struct{ uint32_t enb_ue_s1ap_id; uint32_t mme_ue_s1ap_id; struct sctp_sndrcvinfo enb_sri; - ecm_state_t ecm_state; + ecm_state_t state; srslte::gtpc_f_teid_ie sgw_ctrl_fteid; erab_ctx_t erabs_ctx[MAX_ERABS_PER_UE]; bool eit; diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index dd211cb04..672332868 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -262,38 +262,34 @@ s1ap_ctx_mngmt_proc::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECON m_s1ap_log->info("Received UE Context Release Request. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); m_s1ap_log->console("Received UE Context Release Request. MME-UE S1AP Id %d\n", mme_ue_s1ap_id); - ue_ecm_ctx_t *ue_ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); - if(ue_ecm_ctx == NULL) + ue_ecm_ctx_t *ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); + if(ecm_ctx == NULL) { - m_s1ap_log->info("UE not found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); + m_s1ap_log->info("No UE ECM context to release found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); + m_s1ap_log->console("No UE ECM context to release found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); return false; } - //Delete any context at the SPGW - bool active = false; - for(int i=0;istate == ECM_STATE_CONNECTED) { - if(ue_ecm_ctx->erabs_ctx[i].state != ERAB_DEACTIVATED) //FIXME use ECM state - { - active = true; - //ue_ctx->erabs_ctx[i].state = ERAB_DEACTIVATED; - break; - } + //There are active E-RABs, send release access mearers request + m_mme_gtpc->send_release_access_bearers_request(ecm_ctx->imsi); } - if(active == true) + else { - //There are active E-RABs, send delete session request - m_mme_gtpc->send_delete_session_request(ue_ecm_ctx->imsi); + //No ECM Context to release + m_s1ap_log->info("UE is not ECM connected. No need to release S1-U. MME UE S1AP Id %d\n", mme_ue_s1ap_id); + m_s1ap_log->console("UE is not ECM connected. No need to release S1-U. MME UE S1AP Id %d\n", mme_ue_s1ap_id); } //m_s1ap->delete_ue_ctx(ue_ctx); for(int i=0;ierabs_ctx[i].state = ERAB_DEACTIVATED; + ecm_ctx->erabs_ctx[i].state = ERAB_DEACTIVATED; } //Delete UE context - m_s1ap->delete_ue_ecm_ctx(ue_ecm_ctx->mme_ue_s1ap_id); - - m_s1ap_log->info("Deleted UE Context.\n"); + m_s1ap->delete_ue_ecm_ctx(ecm_ctx->mme_ue_s1ap_id); + m_s1ap_log->info("Deleted UE ECM Context.\n"); return true; } From f3c04949b755ce135fef9488f213e3d7fed60b88 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 8 Mar 2018 16:56:51 +0100 Subject: [PATCH 240/342] PHCH Receive is reset, the current EARFCN becomes the first one in the list. --- srsue/src/phy/phch_recv.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 112cd03b8..7d6a2eec6 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -132,7 +132,11 @@ void phch_recv::reset() next_offset = 0; cell_is_set = false; srate_mode = SRATE_NONE; - current_earfcn = 0; + if (!earfcn.empty()) { + current_earfcn = earfcn[0]; + } else { + current_earfcn = 0; + } sfn_p.reset(); measure_p.reset(); search_p.reset(); From de936b30d1ec54b2e79a45a1835616adf66a3ae7 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 8 Mar 2018 16:17:13 +0000 Subject: [PATCH 241/342] Fixed small bug in send create session request. --- srsepc/src/mme/mme_gtpc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 608b29b6e..799bd8bfd 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -125,7 +125,7 @@ mme_gtpc::send_create_session_request(uint64_t imsi, bool pack_attach) //Check whether this UE is already registed std::map::iterator it = m_imsi_to_gtpc_ctx.find(imsi); - if(it == m_imsi_to_gtpc_ctx.end()) + if(it != m_imsi_to_gtpc_ctx.end()) { m_mme_gtpc_log->warning("Create Session Request being called for an UE with an active GTP-C connection.\n"); m_mme_gtpc_log->warning("Deleting previous GTP-C connection.\n"); From 9b28527423df2267411f13af9ca6dd2747292c88 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 8 Mar 2018 17:59:03 +0000 Subject: [PATCH 242/342] Fixed bug in release access bearers request --- srsepc/src/mme/mme_gtpc.cc | 16 +++++++++++++--- srsepc/src/mme/s1ap.cc | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 799bd8bfd..a4b3bbbe3 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -351,15 +351,25 @@ mme_gtpc::send_release_access_bearers_request(uint64_t imsi) { m_mme_gtpc_log->info("Sending GTP-C Delete Access Bearers Request\n"); srslte::gtpc_pdu rel_req_pdu; - srslte::gtpc_f_teid_ie *sgw_ctrl_fteid = NULL; + srslte::gtp_fteid_t sgw_ctr_fteid; + + //Get S-GW Ctr TEID + std::map::iterator it_ctx = m_imsi_to_gtpc_ctx.find(imsi); + if(it_ctx == m_imsi_to_gtpc_ctx.end()) + { + m_mme_gtpc_log->error("Could not find GTP-C context to remove\n"); + return; + } + sgw_ctr_fteid = it_ctx->second.sgw_ctr_fteid; + //Set GTP-C header srslte::gtpc_header *header = &rel_req_pdu.header; header->teid_present = true; - header->teid = sgw_ctrl_fteid->teid; + header->teid = sgw_ctr_fteid.teid; header->type = srslte::GTPC_MSG_TYPE_RELEASE_ACCESS_BEARERS_REQUEST; srslte::gtpc_release_access_bearers_request *rel_req = &rel_req_pdu.choice.release_access_bearers_request; - m_mme_gtpc_log->info("GTP-C Release Access Berarers Request -- S-GW Control TEID %d\n", sgw_ctrl_fteid->teid ); + m_mme_gtpc_log->info("GTP-C Release Access Berarers Request -- S-GW Control TEID %d\n", sgw_ctr_fteid.teid ); srslte::gtpc_pdu rel_resp_pdu; m_spgw->handle_release_access_bearers_request(&rel_req_pdu, &rel_resp_pdu); diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 19b32ba24..9d3c9e042 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -526,6 +526,7 @@ s1ap::activate_eps_bearer(uint64_t imsi, uint8_t ebi) } ecm_ctx->erabs_ctx[ebi].state = ERAB_ACTIVE; + ecm_ctx->state = ECM_STATE_CONNECTED; m_s1ap_log->info("Activated EPS Bearer\n"); return; } From 9553784e2f5aa5c2839ca8ae70d23e4bf99531f3 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 8 Mar 2018 17:55:48 +0100 Subject: [PATCH 243/342] change phy_log in UE to log_filter --- lib/include/srslte/common/log.h | 2 ++ srsue/hdr/phy/phy.h | 6 +++--- srsue/hdr/ue.h | 2 +- srsue/src/phy/phy.cc | 2 +- srsue/src/ue.cc | 3 +++ srsue/test/mac/mac_test.cc | 4 ++-- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/include/srslte/common/log.h b/lib/include/srslte/common/log.h index ff3a31eaa..360482c47 100644 --- a/lib/include/srslte/common/log.h +++ b/lib/include/srslte/common/log.h @@ -84,6 +84,8 @@ public: level_text_short = true; } + virtual ~log() {}; + // This function shall be called at the start of every tti for printing tti void step(uint32_t tti_) { tti = tti_; diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index 0894a98fb..95140f8cd 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -28,7 +28,7 @@ #define UEPHY_H #include "srslte/srslte.h" -#include "srslte/common/log.h" +#include "srslte/common/log_filter.h" #include "phy/phy_metrics.h" #include "phy/phch_recv.h" #include "phy/prach.h" @@ -53,7 +53,7 @@ public: bool init(srslte::radio_multi *radio_handler, mac_interface_phy *mac, rrc_interface_phy *rrc, - std::vector log_vec, + std::vector log_vec, phy_args_t *args = NULL); void stop(); @@ -158,7 +158,7 @@ private: const static int WORKERS_THREAD_PRIO = 0; srslte::radio_multi *radio_handler; - std::vector log_vec; + std::vector log_vec; srslte::log *log_h; srslte::log *log_phy_lib_h; srsue::mac_interface_phy *mac; diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index d1343c68f..2aa7157e2 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -103,7 +103,7 @@ private: srslte::logger *logger; // rf_log is on ue_base - std::vector phy_log; + std::vector phy_log; srslte::log_filter mac_log; srslte::log_filter rlc_log; srslte::log_filter pdcp_log; diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index e4b618158..5c69d567d 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -120,7 +120,7 @@ bool phy::check_args(phy_args_t *args) } bool phy::init(srslte::radio_multi* radio_handler, mac_interface_phy *mac, rrc_interface_phy *rrc, - std::vector log_vec, phy_args_t *phy_args) { + std::vector log_vec, phy_args_t *phy_args) { mlockall(MCL_CURRENT | MCL_FUTURE); diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 381cb52bf..1d83f087e 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -44,6 +44,9 @@ ue::ue() ue::~ue() { + for (uint32_t i = 0; i < phy_log.size(); i++) { + delete(phy_log[i]); + } } bool ue::init(all_args_t *args_) diff --git a/srsue/test/mac/mac_test.cc b/srsue/test/mac/mac_test.cc index b76ab2f95..3d21720d4 100644 --- a/srsue/test/mac/mac_test.cc +++ b/srsue/test/mac/mac_test.cc @@ -451,12 +451,12 @@ int main(int argc, char *argv[]) exit(1); } - std::vector phy_log; + std::vector phy_log; srslte::log_filter *mylog = new srslte::log_filter("PHY"); char tmp[16]; sprintf(tmp, "PHY%d",0); - phy_log.push_back((srslte::log*) mylog); + phy_log.push_back(mylog); switch (prog_args.verbose) { case 1: From 44b1748a8752b61036333c39e83dcaa6239259aa Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 8 Mar 2018 17:56:52 +0100 Subject: [PATCH 244/342] fix mem leak in sync --- lib/src/phy/sync/sync.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/src/phy/sync/sync.c b/lib/src/phy/sync/sync.c index c948a53d4..39bd98141 100644 --- a/lib/src/phy/sync/sync.c +++ b/lib/src/phy/sync/sync.c @@ -152,21 +152,19 @@ clean_exit: void srslte_sync_free(srslte_sync_t *q) { if (q) { - srslte_pss_free(&q->pss); srslte_sss_free(&q->sss); srslte_cfo_free(&q->cfo_corr_frame); srslte_cfo_free(&q->cfo_corr_symbol); srslte_cp_synch_free(&q->cp_synch); - if (q->cfo_i_initiated) { - for (int i=0;i<2;i++) { - if (q->cfo_i_corr[i]) { - free(q->cfo_i_corr[i]); - } - srslte_pss_free(&q->pss_i[i]); + for (int i = 0; i < 2; i++) { + if (q->cfo_i_corr[i]) { + free(q->cfo_i_corr[i]); } + srslte_pss_free(&q->pss_i[i]); } + if (q->temp) { free(q->temp); } From cbda94f0a6b9395084946db9ba5ea07e4917ebf2 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 8 Mar 2018 17:58:11 +0100 Subject: [PATCH 245/342] fix mem leak in phch_recv --- srsue/hdr/phy/phch_recv.h | 2 ++ srsue/src/phy/phch_recv.cc | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index d77e489ae..7a04e4b10 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -199,6 +199,7 @@ private: uint32_t offset; } cell_info_t; void init(srslte::log *log_h, bool sic_pss_enabled, uint32_t max_sf_window); + void deinit(); void reset(); int find_cells(cf_t *input_buffer, float rx_gain_offset, srslte_cell_t current_cell, uint32_t nof_sf, cell_info_t found_cells[MAX_CELLS]); private: @@ -220,6 +221,7 @@ private: // Class to perform intra-frequency measurements class intra_measure : public thread { public: + ~intra_measure(); void init(phch_common *common, rrc_interface_phy *rrc, srslte::log *log_h); void stop(); void add_cell(int pci); diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 7d6a2eec6..a96b9c545 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -711,6 +711,12 @@ void phch_recv::run_thread() mac->tti_clock(tti); tti = (tti+1) % 10240; } + + for (int i=0;icurrent_earfcn = earfcn; current_sflen = SRSLTE_SF_LEN_PRB(cell.nof_prb); From 43811e1886f73c7fcdd29fc56c75a63588fae6ad Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 8 Mar 2018 18:00:35 +0100 Subject: [PATCH 246/342] deallocate used buffers in buffer_pool dtor --- lib/include/srslte/common/buffer_pool.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index 035fbc661..76634a697 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -72,6 +72,10 @@ public: delete available.top(); available.pop(); } + + for (uint32_t i = 0; i < used.size(); i++) { + delete used[i]; + } } void print_all_buffers() From 5335f046ff6a0e42cf7c5b1860fd6f308e1aba46 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 8 Mar 2018 18:03:16 +0100 Subject: [PATCH 247/342] dealloc mutex and cond in msg_queue --- lib/include/srslte/common/msg_queue.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/include/srslte/common/msg_queue.h b/lib/include/srslte/common/msg_queue.h index bca4c5388..e8b8c742a 100644 --- a/lib/include/srslte/common/msg_queue.h +++ b/lib/include/srslte/common/msg_queue.h @@ -56,6 +56,9 @@ public: ~msg_queue() { + pthread_mutex_destroy(&mutex); + pthread_cond_destroy(¬_empty); + pthread_cond_destroy(¬_full); delete [] buf; } From b85a220145df84c7fb95c70f114849f2fe7f3b62 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 8 Mar 2018 16:35:37 -0500 Subject: [PATCH 248/342] Fix HO not setting serving cell --- srsue/src/upper/rrc.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index fdd461ebb..acb91e5fd 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -617,11 +617,6 @@ void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { int cell_idx = -1; bool found = true; - if (ho_syncing && phy_cell.id == ho_target_pci) { - ho_synced(ho_target_pci); - return; - } - pthread_mutex_lock(&mutex); if (serving_cell->equals(earfcn, phy_cell.id)) { @@ -665,6 +660,9 @@ void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { found?"Updating":"Adding", cell_idx>=0?"neighbour":"serving", earfcn, phy_cell.id, rsrp); + if (ho_syncing && phy_cell.id == ho_target_pci) { + ho_synced(ho_target_pci); + } } From 3afb93fcb9ad1ca42a407714b374d81b1efc01d9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 9 Mar 2018 17:05:46 +0100 Subject: [PATCH 249/342] exit the UE with q in console --- srsue/src/main.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/srsue/src/main.cc b/srsue/src/main.cc index ef38a7f80..f5df0af2d 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -422,6 +422,9 @@ void *input_loop(void *m) { cout << "Enter t to restart trace." << endl; } metrics_screen.toggle_print(do_metrics); + } else + if ('q' == key) { + running = false; } } } From d5478ff7a2b4b72e4cfdc3a9e63089d160053100 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 9 Mar 2018 16:25:59 +0000 Subject: [PATCH 250/342] Starting to use EMM state to know whether attach request or service request are initiating the NAS. --- srsepc/hdr/mme/mme_gtpc.h | 4 +- srsepc/hdr/mme/s1ap_common.h | 5 +- srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h | 2 +- srsepc/hdr/spgw/spgw.h | 2 +- srsepc/src/mme/mme_gtpc.cc | 9 ++-- srsepc/src/mme/s1ap.cc | 9 +++- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 9 ++-- srsepc/src/mme/s1ap_nas_transport.cc | 75 +++++++++++++++------------ srsepc/src/spgw/spgw.cc | 8 +-- 9 files changed, 71 insertions(+), 52 deletions(-) diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index 6e3ab76b1..23e6acf0a 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -52,8 +52,8 @@ public: bool init(srslte::log_filter *mme_gtpc_log); uint32_t get_new_ctrl_teid(); - void send_create_session_request(uint64_t imsi, bool pack_attach); - void handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pack_attach); + void send_create_session_request(uint64_t imsi); + void handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu); void send_modify_bearer_request(uint64_t imsi, erab_ctx_t *bearer_ctx); void handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu); void send_release_access_bearers_request(uint64_t imsi); diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index 4cda8376f..7ffaf3434 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -136,9 +136,12 @@ typedef struct{ LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT guti; eps_security_ctx_t security_ctxt; uint8_t procedure_transaction_id; - emm_state_t emm_state; + emm_state_t state; uint32_t mme_ue_s1ap_id; uint8_t attach_type; + //enum nas_init_msg init_msg; + //enum emm_connection_management conn_mngmnt_state; + //enum emm_common_proc common_proc_state; } ue_emm_ctx_t; typedef struct{ diff --git a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h index 1886b9d50..44458aea6 100644 --- a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h @@ -48,7 +48,7 @@ public: void init(void); //bool send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte::gtpc_create_session_response *cs_resp, struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid); - bool send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, ue_ecm_ctx_t *ecm_ctx, erab_ctx_t *erab_ctx, bool pack_attach); + bool send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, ue_ecm_ctx_t *ecm_ctx, erab_ctx_t *erab_ctx); bool handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *in_ctxt_resp); bool handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ue_rel, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); bool send_ue_context_release_command(ue_ecm_ctx_t *ecm_ctx, srslte::byte_buffer_t *reply_buffer); diff --git a/srsepc/hdr/spgw/spgw.h b/srsepc/hdr/spgw/spgw.h index 14868c571..c68626f9c 100644 --- a/srsepc/hdr/spgw/spgw.h +++ b/srsepc/hdr/spgw/spgw.h @@ -73,7 +73,7 @@ public: void stop(); void run_thread(); - void handle_create_session_request(struct srslte::gtpc_create_session_request *cs_req, struct srslte::gtpc_pdu *cs_resp_pdu,bool pack_attach); + void handle_create_session_request(struct srslte::gtpc_create_session_request *cs_req, struct srslte::gtpc_pdu *cs_resp_pdu); void handle_modify_bearer_request(struct srslte::gtpc_pdu *mb_req_pdu, struct srslte::gtpc_pdu *mb_resp_pdu); void handle_delete_session_request(struct srslte::gtpc_pdu *del_req_pdu, struct srslte::gtpc_pdu *del_resp_pdu); void handle_release_access_bearers_request(struct srslte::gtpc_pdu *rel_req_pdu, struct srslte::gtpc_pdu *rel_resp_pdu); diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index a4b3bbbe3..595166494 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -88,7 +88,7 @@ mme_gtpc::get_new_ctrl_teid() return m_next_ctrl_teid++; //FIXME Use a Id pool? } void -mme_gtpc::send_create_session_request(uint64_t imsi, bool pack_attach) +mme_gtpc::send_create_session_request(uint64_t imsi) { m_mme_gtpc_log->info("Sending Create Session Request.\n"); m_mme_gtpc_log->console("Sending Create Session Request.\n"); @@ -151,12 +151,12 @@ mme_gtpc::send_create_session_request(uint64_t imsi, bool pack_attach) bzero(>pc_ctx,sizeof(gtpc_ctx_t)); gtpc_ctx.mme_ctr_fteid = cs_req->sender_f_teid; m_imsi_to_gtpc_ctx.insert(std::pair(imsi,gtpc_ctx)); - m_spgw->handle_create_session_request(cs_req, &cs_resp_pdu, pack_attach); + m_spgw->handle_create_session_request(cs_req, &cs_resp_pdu); } void -mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pack_attach) +mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu) { struct srslte::gtpc_create_session_response *cs_resp = & cs_resp_pdu->choice.create_session_response; m_mme_gtpc_log->info("Received Create Session Response\n"); @@ -243,7 +243,8 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pac erab_ctx->pdn_addr_alloc= cs_resp->paa; erab_ctx->sgw_s1u_fteid = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid; - m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, erab_ctx, pack_attach); + m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, erab_ctx); + return; } diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 9d3c9e042..845675057 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -350,9 +350,16 @@ s1ap::delete_enb_ctx(int32_t assoc_id) void s1ap::add_new_ue_emm_ctx(const ue_emm_ctx_t &ue_emm_ctx) { + std::map::iterator emm_ctx_it = m_imsi_to_ue_emm_ctx.find(ue_emm_ctx.imsi); + if(emm_ctx_it != m_imsi_to_ue_emm_ctx.end()) + { + m_s1ap_log->warning("EMM Context already exists. Replacing EMM Context\n"); + delete emm_ctx_it->second; + m_imsi_to_ue_emm_ctx.erase(emm_ctx_it); + } + ue_emm_ctx_t *ue_ptr = new ue_emm_ctx_t; memcpy(ue_ptr,&ue_emm_ctx,sizeof(ue_emm_ctx)); - //This map will store UEs EMM context m_imsi_to_ue_emm_ctx.insert(std::pair(ue_ptr->imsi,ue_ptr)); } diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 672332868..a1ed611ee 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -79,8 +79,7 @@ s1ap_ctx_mngmt_proc::init(void) bool s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, ue_ecm_ctx_t *ecm_ctx, - erab_ctx_t *erab_ctx, - bool pack_attach) + erab_ctx_t *erab_ctx) { int s1mme = m_s1ap->get_s1_mme(); @@ -161,13 +160,13 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, m_s1ap_log->info_hex(emm_ctx->security_ctxt.k_enb, 32, "Initial Context Setup Request -- Key eNB\n"); srslte::byte_buffer_t *nas_buffer = m_pool->allocate(); - if(pack_attach) + if(emm_ctx->state == EMM_STATE_DEREGISTERED) { - pack_attach = false; + //Attach procedure initiated from an attach request m_s1ap_nas_transport->pack_attach_accept(emm_ctx, ecm_ctx, erab_ctx_req, &erab_ctx->pdn_addr_alloc, nas_buffer); - } + LIBLTE_ERROR_ENUM err = liblte_s1ap_pack_s1ap_pdu(&pdu, (LIBLTE_BYTE_MSG_STRUCT*)reply_buffer); if(err != LIBLTE_SUCCESS) { diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 11eb2b9af..75a53aa40 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -107,14 +107,15 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA m_s1ap_log->console("Received Service Request \n"); if(!init_ue->S_TMSI_present) { - m_s1ap_log->error("Service request -- S-TMSI not present\n "); + m_s1ap_log->error("Service request -- S-TMSI not present\n"); m_s1ap_log->console("Service request -- S-TMSI not present\n" ); + return false; } uint32_t *m_tmsi = (uint32_t*) &init_ue->S_TMSI.m_TMSI.buffer; uint32_t enb_ue_s1ap_id = init_ue->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID; - m_s1ap_log->info("Service request -- S-TMSI 0x%x\n ", ntohl(*m_tmsi)); + m_s1ap_log->info("Service request -- S-TMSI 0x%x\n", ntohl(*m_tmsi)); m_s1ap_log->console("Service request -- S-TMSI 0x%x\n", ntohl(*m_tmsi) ); - m_s1ap_log->info("Service request -- eNB UE S1AP Id %d\n ", enb_ue_s1ap_id); + m_s1ap_log->info("Service request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); m_s1ap_log->console("Service request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); handle_nas_service_request(ntohl(*m_tmsi), enb_ue_s1ap_id, nas_msg, reply_buffer,reply_flag, enb_sri); return false; @@ -320,7 +321,7 @@ s1ap_nas_transport::handle_nas_attach_request(uint32_t enb_ue_s1ap_id, //Get attach type from attach request if(attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI) - { + { m_s1ap_log->console("Attach Request -- IMSI-style attach request\n"); m_s1ap_log->info("Attach Request -- IMSI-style attach request\n"); handle_nas_imsi_attach_request(enb_ue_s1ap_id, attach_req, pdn_con_req, reply_buffer, reply_flag, enb_sri); @@ -592,7 +593,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); //Create session request m_s1ap_log->console("GUTI Attach -- NAS Integrity OK."); - m_mme_gtpc->send_create_session_request(ue_emm_ctx->imsi,true); + m_mme_gtpc->send_create_session_request(ue_emm_ctx->imsi); *reply_flag = false; //No reply needed return true; } @@ -643,22 +644,22 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, return true; } - ue_emm_ctx_t *ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(it->second); - if(ue_emm_ctx == NULL) + ue_emm_ctx_t *emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(it->second); + if(emm_ctx == NULL || emm_ctx->state != EMM_STATE_REGISTERED) { - m_s1ap_log->console("Could not find UE security context\n"); - m_s1ap_log->error("Could not find UE security context\n"); + m_s1ap_log->console("UE is not EMM-Registered.\n"); + m_s1ap_log->error("UE is not EMM-Registered.\n"); pack_service_reject(reply_buffer, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED, enb_ue_s1ap_id); *reply_flag = true; return true; } - ue_emm_ctx->security_ctxt.ul_nas_count++; - mac_valid = short_integrity_check(ue_emm_ctx,nas_msg); + emm_ctx->security_ctxt.ul_nas_count++; + mac_valid = short_integrity_check(emm_ctx,nas_msg); if(mac_valid) { m_s1ap_log->console("Service Request -- Short MAC valid\n"); m_s1ap_log->info("Service Request -- Short MAC valid\n"); - ue_ecm_ctx_t *ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(ue_emm_ctx->mme_ue_s1ap_id); + ue_ecm_ctx_t *ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(emm_ctx->mme_ue_s1ap_id); if(ecm_ctx !=NULL) { //Service request to Connected UE. @@ -672,7 +673,7 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, m_s1ap_log->info("Service Request -- User has ECM context already\n"); //m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); int default_bearer_id = 5; - m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ue_emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[default_bearer_id],false); + m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[default_bearer_id]); } else { @@ -683,9 +684,9 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, m_s1ap_log->console("Service Request -- User without ECM context\n"); m_s1ap_log->info("Service Request -- User without ECM context\n"); //Create ECM context - ue_ecm_ctx.imsi = ue_emm_ctx->imsi; + ue_ecm_ctx.imsi = emm_ctx->imsi; ue_ecm_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); - ue_emm_ctx->mme_ue_s1ap_id = ue_ecm_ctx.mme_ue_s1ap_id; + emm_ctx->mme_ue_s1ap_id = ue_ecm_ctx.mme_ue_s1ap_id; //Set eNB information ue_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; memcpy(&ue_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); @@ -703,12 +704,11 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); //Re-generate K_eNB - liblte_security_generate_k_enb(ue_emm_ctx->security_ctxt.k_asme, ue_emm_ctx->security_ctxt.ul_nas_count, ue_emm_ctx->security_ctxt.k_enb); - m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",ue_emm_ctx->security_ctxt.ul_nas_count); + liblte_security_generate_k_enb(emm_ctx->security_ctxt.k_asme, emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.k_enb); + m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",emm_ctx->security_ctxt.ul_nas_count); //FIXME Send Modify context request OR send ctx release command and wait for the reply. - m_mme_gtpc->send_create_session_request(ue_ecm_ctx.imsi,false); + m_mme_gtpc->send_create_session_request(ue_ecm_ctx.imsi); m_s1ap_log->console("UE ESM Ctr TEID %d\n", ue_ecm_ctx.sgw_ctrl_fteid.teid); - // m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ue_); } } else @@ -823,14 +823,14 @@ s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas { //FIXME The packging of GTP-C messages is not ready. //This means that GTP-U tunnels are created with function calls, as opposed to GTP-C. - m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi,true); + m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi); *reply_flag = false; //No reply needed } return true; } bool -s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) +s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) { LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_comp; @@ -853,7 +853,13 @@ s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, u return false; } - m_s1ap_log->console("Unpacked Attached Complete Message\n"); + ue_emm_ctx_t *emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ecm_ctx->imsi); + if(emm_ctx == NULL) + { + m_s1ap_log->error("Received Attach complete, but could not find UE's EMM Context.\n"); + } + + m_s1ap_log->console("Unpacked Attached Complete Message. IMSI %d\n", emm_ctx->imsi); m_s1ap_log->console("Unpacked Activate Default EPS Bearer message. EPS Bearer id %d\n",act_bearer.eps_bearer_id); //ue_ctx->erabs_ctx[act_bearer->eps_bearer_id].enb_fteid; if(act_bearer.eps_bearer_id < 5 || act_bearer.eps_bearer_id > 15) @@ -861,14 +867,17 @@ s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, u m_s1ap_log->error("EPS Bearer ID out of range\n"); return false; } - m_mme_gtpc->send_modify_bearer_request(ue_ecm_ctx->imsi, &ue_ecm_ctx->erabs_ctx[act_bearer.eps_bearer_id]); - - //Send reply to eNB - m_s1ap_log->console("Packing EMM infromationi\n"); - *reply_flag = pack_emm_information(ue_ecm_ctx, reply_msg); - m_s1ap_log->console("Sending EMM infromation, bytes %d\n",reply_msg->N_bytes); - m_s1ap_log->info("Sending EMM infromation\n"); - + if(emm_ctx->state == EMM_STATE_DEREGISTERED) + { + //Attach requested from attach request + m_mme_gtpc->send_modify_bearer_request(ecm_ctx->imsi, &ecm_ctx->erabs_ctx[act_bearer.eps_bearer_id]); + //Send reply to eNB + m_s1ap_log->console("Packing EMM infromationi\n"); + *reply_flag = pack_emm_information(ecm_ctx, reply_msg); + m_s1ap_log->console("Sending EMM infromation, bytes %d\n",reply_msg->N_bytes); + m_s1ap_log->info("Sending EMM infromation\n"); + } + emm_ctx->state = EMM_STATE_REGISTERED; return true; } @@ -897,7 +906,7 @@ s1ap_nas_transport::handle_esm_information_response(srslte::byte_buffer_t *nas_m //FIXME The packging of GTP-C messages is not ready. //This means that GTP-U tunnels are created with function calls, as opposed to GTP-C. - m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi,true); + m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi); return true; } @@ -1756,7 +1765,7 @@ s1ap_nas_transport::pack_emm_information( ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte LIBLTE_MME_EMM_INFORMATION_MSG_STRUCT emm_info; emm_info.full_net_name_present = true; - emm_info.full_net_name.name = std::string("srsLTE"); + emm_info.full_net_name.name = std::string("Software Radio Systems LTE"); emm_info.full_net_name.add_ci = LIBLTE_MME_ADD_CI_DONT_ADD; emm_info.short_net_name_present = true; emm_info.short_net_name.name = std::string("srsLTE"); @@ -1771,7 +1780,7 @@ s1ap_nas_transport::pack_emm_information( ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte return false; uint8_t sec_hdr_type =2; - //ue_emm_ctx->security_ctxt.dl_nas_count++; + // ue_emm_ctx->security_ctxt.dl_nas_count++; LIBLTE_ERROR_ENUM err = liblte_mme_pack_emm_information_msg(&emm_info, sec_hdr_type, ue_emm_ctx->security_ctxt.dl_nas_count, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); if(err != LIBLTE_SUCCESS) { diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index b16b89c27..6444b8503 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -144,8 +144,8 @@ spgw::stop() std::map::iterator it = m_teid_to_tunnel_ctx.begin(); //Map control TEID to tunnel ctx. Usefull to get reply ctrl TEID, UE IP, etc. while(it!=m_teid_to_tunnel_ctx.end()) { - m_spgw_log->info("Deleting SP-GW Tunnel. IMSI: %lu\n", it->second->imsi); - m_spgw_log->console("Deleting SP-GW Tunnel. IMSI: %lu\n", it->second->imsi); + m_spgw_log->info("Deleting SP-GW GTP-C Tunnel. IMSI: %lu\n", it->second->imsi); + m_spgw_log->console("Deleting SP-GW GTP-C Tunnel. IMSI: %lu\n", it->second->imsi); delete it->second; m_teid_to_tunnel_ctx.erase(it++); } @@ -437,7 +437,7 @@ spgw::get_new_ue_ipv4() } void -spgw::handle_create_session_request(struct srslte::gtpc_create_session_request *cs_req, struct srslte::gtpc_pdu *cs_resp_pdu, bool pack_attach) +spgw::handle_create_session_request(struct srslte::gtpc_create_session_request *cs_req, struct srslte::gtpc_pdu *cs_resp_pdu) { srslte::gtpc_header *header = &cs_resp_pdu->header; srslte::gtpc_create_session_response *cs_resp = &cs_resp_pdu->choice.create_session_response; @@ -492,7 +492,7 @@ spgw::handle_create_session_request(struct srslte::gtpc_create_session_request * cs_resp->paa.ipv4_present = true; cs_resp->paa.ipv4 = ue_ip; m_spgw_log->info("Sending Create Session Response\n"); - m_mme_gtpc->handle_create_session_response(cs_resp_pdu, pack_attach ); + m_mme_gtpc->handle_create_session_response(cs_resp_pdu); return; } From ff8818590a4b1fdf7644a1e7953d4825c2c5397c Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 9 Mar 2018 21:30:33 +0000 Subject: [PATCH 251/342] Changing SPGW's handle_create_session_request to check weather GTP context already exists. --- srsepc/hdr/spgw/spgw.h | 6 ++ srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 14 ++-- srsepc/src/mme/s1ap_nas_transport.cc | 10 +-- srsepc/src/spgw/spgw.cc | 92 ++++++++++++++++++++++----- 4 files changed, 96 insertions(+), 26 deletions(-) diff --git a/srsepc/hdr/spgw/spgw.h b/srsepc/hdr/spgw/spgw.h index c68626f9c..e82d3f6ea 100644 --- a/srsepc/hdr/spgw/spgw.h +++ b/srsepc/hdr/spgw/spgw.h @@ -95,6 +95,10 @@ private: uint64_t get_new_user_teid(); in_addr_t get_new_ue_ipv4(); + spgw_tunnel_ctx_t* create_gtp_ctx(struct srslte::gtpc_create_session_request *cs_req); + bool delete_gtp_ctx(uint32_t ctrl_teid); + + bool m_running; srslte::byte_buffer_pool *m_pool; mme_gtpc *m_mme_gtpc; @@ -113,6 +117,8 @@ private: sockaddr_in m_s1u_addr; pthread_mutex_t m_mutex; + + std::map m_imsi_to_ctr_teid; //IMSI to control TEID map. Important to check if UE is previously connected std::map m_teid_to_tunnel_ctx; //Map control TEID to tunnel ctx. Usefull to get reply ctrl TEID, UE IP, etc. std::map m_ip_to_teid; //Map IP to User-plane TEID for downlink traffic diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index a1ed611ee..eacccb5c7 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -163,6 +163,8 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, if(emm_ctx->state == EMM_STATE_DEREGISTERED) { //Attach procedure initiated from an attach request + m_s1ap_log->console("Adding attach accept to Initial Context Setup Request\n"); + m_s1ap_log->info("Adding attach accept to Initial Context Setup Request\n"); m_s1ap_nas_transport->pack_attach_accept(emm_ctx, ecm_ctx, erab_ctx_req, &erab_ctx->pdn_addr_alloc, nas_buffer); } @@ -202,12 +204,17 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, bool s1ap_ctx_mngmt_proc::handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *in_ctxt_resp) { - static bool send_modify = false; uint32_t mme_ue_s1ap_id = in_ctxt_resp->MME_UE_S1AP_ID.MME_UE_S1AP_ID; ue_ecm_ctx_t *ue_ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); if (ue_ecm_ctx == NULL) { - m_s1ap_log->error("Could not find UE's context in active UE's map\n"); + m_s1ap_log->error("Could not find UE's ECM context in active UE's map\n"); + return false; + } + ue_emm_ctx_t *emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); + if (emm_ctx == NULL) + { + m_s1ap_log->error("Could not find UE's EMM context in active UE's map\n"); return false; } @@ -243,11 +250,10 @@ s1ap_ctx_mngmt_proc::handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_I m_s1ap_log->console("E-RAB Context -- eNB TEID 0x%x; eNB GTP-U Address %s\n", erab_ctx->enb_fteid.teid, enb_addr_str); } - if(send_modify) + if(emm_ctx->state == EMM_STATE_DEREGISTERED) { m_mme_gtpc->send_modify_bearer_request(ue_ecm_ctx->imsi, &ue_ecm_ctx->erabs_ctx[5]); } - send_modify = true; return true; } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 75a53aa40..fb464c26f 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -363,7 +363,7 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, ue_emm_ctx.imsi += attach_req.eps_mobile_id.imsi[i]*std::pow(10,14-i); } ue_emm_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); - + ue_emm_ctx.state = EMM_STATE_DEREGISTERED; //Save UE network capabilities memcpy(&ue_emm_ctx.security_ctxt.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT)); ue_emm_ctx.security_ctxt.ms_network_cap_present = attach_req.ms_network_cap_present; @@ -671,9 +671,9 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, //Delete eNB context and connect. m_s1ap_log->console("Service Request -- User has ECM context already\n"); m_s1ap_log->info("Service Request -- User has ECM context already\n"); - //m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); - int default_bearer_id = 5; - m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[default_bearer_id]); + m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); + //int default_bearer_id = 5; + //m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[default_bearer_id]); } else { @@ -1780,7 +1780,7 @@ s1ap_nas_transport::pack_emm_information( ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte return false; uint8_t sec_hdr_type =2; - // ue_emm_ctx->security_ctxt.dl_nas_count++; + ue_emm_ctx->security_ctxt.dl_nas_count++; LIBLTE_ERROR_ENUM err = liblte_mme_pack_emm_information_msg(&emm_info, sec_hdr_type, ue_emm_ctx->security_ctxt.dl_nas_count, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); if(err != LIBLTE_SUCCESS) { diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index 6444b8503..0acb37041 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -417,6 +417,10 @@ spgw::handle_s1u_pdu(srslte::byte_buffer_t *msg) } return; } + +/* + * Helper Functions + */ uint64_t spgw::get_new_ctrl_teid() { @@ -436,61 +440,115 @@ spgw::get_new_ue_ipv4() return ntohl(m_h_next_ue_ip);//FIXME Tmp hack } -void -spgw::handle_create_session_request(struct srslte::gtpc_create_session_request *cs_req, struct srslte::gtpc_pdu *cs_resp_pdu) +spgw_tunnel_ctx_t* +spgw::create_gtp_ctx(struct srslte::gtpc_create_session_request *cs_req) { - srslte::gtpc_header *header = &cs_resp_pdu->header; - srslte::gtpc_create_session_response *cs_resp = &cs_resp_pdu->choice.create_session_response; - - - m_spgw_log->info("Received Create Session Request\n"); - //Setup uplink control TEID + //Setup uplink control TEID uint64_t spgw_uplink_ctrl_teid = get_new_ctrl_teid(); //Setup uplink user TEID uint64_t spgw_uplink_user_teid = get_new_user_teid(); //Allocate UE IP - //in_addr_t ue_ip = get_new_ue_ipv4(); - in_addr_t ue_ip = inet_addr("172.16.0.2"); + in_addr_t ue_ip = get_new_ue_ipv4(); + //in_addr_t ue_ip = inet_addr("172.16.0.2"); uint8_t default_bearer_id = 5; + m_spgw_log->console("SPGW: Allocated Ctrl TEID %d\n", spgw_uplink_ctrl_teid); + m_spgw_log->console("SPGW: Allocated User TEID %d\n", spgw_uplink_user_teid); + struct in_addr ue_ip_; + ue_ip_.s_addr=ue_ip; + m_spgw_log->console("SPGW: Allocate UE IP %s\n", inet_ntoa(ue_ip_)); + + //Save the UE IP to User TEID map spgw_tunnel_ctx_t *tunnel_ctx = new spgw_tunnel_ctx_t; + bzero(tunnel_ctx,sizeof(spgw_tunnel_ctx_t)); + tunnel_ctx->imsi = cs_req->imsi; tunnel_ctx->ebi = default_bearer_id; tunnel_ctx->up_user_fteid.teid = spgw_uplink_user_teid; tunnel_ctx->up_user_fteid.ipv4 = m_s1u_addr.sin_addr.s_addr; tunnel_ctx->dw_ctrl_fteid.teid = cs_req->sender_f_teid.teid; tunnel_ctx->dw_ctrl_fteid.ipv4 = cs_req->sender_f_teid.ipv4; - + tunnel_ctx->up_ctrl_fteid.teid = spgw_uplink_ctrl_teid; tunnel_ctx->ue_ipv4 = ue_ip; m_teid_to_tunnel_ctx.insert(std::pair(spgw_uplink_ctrl_teid,tunnel_ctx)); + m_imsi_to_ctr_teid.insert(std::pair(cs_req->imsi,spgw_uplink_ctrl_teid)); + return tunnel_ctx; +} + +bool +spgw::delete_gtp_ctx(uint32_t ctrl_teid) +{ + spgw_tunnel_ctx_t *tunnel_ctx; + if(!m_teid_to_tunnel_ctx.count(ctrl_teid)){ + m_spgw_log->error("Could not find GTP context to delete.\n"); + return false; + } + tunnel_ctx = m_teid_to_tunnel_ctx[ctrl_teid]; + + //Remove GTP-U connections, if any. + if(m_ip_to_teid.count(tunnel_ctx->ue_ipv4)) + { + pthread_mutex_lock(&m_mutex); + m_ip_to_teid.erase(tunnel_ctx->ue_ipv4); + pthread_mutex_unlock(&m_mutex); + } + //Remove Ctrl TEID from IMSI to control TEID map + m_imsi_to_ctr_teid.erase(tunnel_ctx->imsi); + + //Remove GTP context from control TEID mapping + m_teid_to_tunnel_ctx.erase(ctrl_teid); + delete tunnel_ctx; + return true; +} + +void +spgw::handle_create_session_request(struct srslte::gtpc_create_session_request *cs_req, struct srslte::gtpc_pdu *cs_resp_pdu) +{ + m_spgw_log->info("Received Create Session Request\n"); + spgw_tunnel_ctx_t *tunnel_ctx; + int default_bearer_id = 5; + //Check if IMSI has active GTP-C and/or GTP-U + bool gtpc_present = m_imsi_to_ctr_teid.count(cs_req->imsi); + if(gtpc_present) + { + m_spgw_log->console("SPGW: GTP-C context for IMSI %015ul already exists.\n", cs_req->imsi); + delete_gtp_ctx(m_imsi_to_ctr_teid[cs_req->imsi]); + m_spgw_log->console("SPGW: Deleted previous context.\n"); + } + + m_spgw_log->info("Creating new GTP-C context\n"); + tunnel_ctx = create_gtp_ctx(cs_req); //Create session response message + srslte::gtpc_header *header = &cs_resp_pdu->header; + srslte::gtpc_create_session_response *cs_resp = &cs_resp_pdu->choice.create_session_response; + //Setup GTP-C header header->piggyback = false; header->teid_present = true; - header->teid = cs_req->sender_f_teid.teid; //Send create session requesponse to the CS Request TEID + header->teid = tunnel_ctx->dw_ctrl_fteid.teid; //Send create session requesponse to the UE's MME Ctrl TEID header->type = srslte::GTPC_MSG_TYPE_CREATE_SESSION_RESPONSE; + //Initialize to zero bzero(cs_resp,sizeof(struct srslte::gtpc_create_session_response)); //Setup Cause cs_resp->cause.cause_value = srslte::GTPC_CAUSE_VALUE_REQUEST_ACCEPTED; //Setup sender F-TEID (ctrl) cs_resp->sender_f_teid.ipv4_present = true; - cs_resp->sender_f_teid.teid = spgw_uplink_ctrl_teid; - cs_resp->sender_f_teid.ipv4 = 0;//FIXME This is not relevant, as the GTP-C is not transmitted over sockets yet. + cs_resp->sender_f_teid = tunnel_ctx->up_ctrl_fteid; + //Bearer context created cs_resp->eps_bearer_context_created.ebi = default_bearer_id; cs_resp->eps_bearer_context_created.cause.cause_value = srslte::GTPC_CAUSE_VALUE_REQUEST_ACCEPTED; cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid_present=true; - cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.teid = spgw_uplink_user_teid; - cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.ipv4 = m_s1u_addr.sin_addr.s_addr; + cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid = tunnel_ctx->up_user_fteid; //Fill in the PAA cs_resp->paa_present = true; cs_resp->paa.pdn_type = srslte::GTPC_PDN_TYPE_IPV4; cs_resp->paa.ipv4_present = true; - cs_resp->paa.ipv4 = ue_ip; + cs_resp->paa.ipv4 = tunnel_ctx->ue_ipv4; m_spgw_log->info("Sending Create Session Response\n"); m_mme_gtpc->handle_create_session_response(cs_resp_pdu); return; From 6ca6919694fc6b374c9e3ee710b066ed0fafaf16 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 11 Mar 2018 21:47:15 -0400 Subject: [PATCH 252/342] Handle T300 expiry to avoid blocking on RLC TM UL CCCH when ConnectionRequest fails --- srsue/hdr/upper/rrc.h | 2 +- srsue/src/upper/rrc.cc | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 8d092051a..5c9899eab 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -341,7 +341,7 @@ private: srslte::mac_interface_timers *mac_timers; uint32_t n310_cnt, N310; uint32_t n311_cnt, N311; - uint32_t t301, t310, t311, t304; + uint32_t t300, t301, t310, t311, t304; // Radio bearers typedef enum{ diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index acb91e5fd..1f0c6eb94 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -113,6 +113,7 @@ void rrc::init(phy_interface_rrc *phy_, args.nof_supported_bands = 1; args.feature_group = 0xe6041c00; + t300 = mac_timers->timer_get_unique_id(); t301 = mac_timers->timer_get_unique_id(); t310 = mac_timers->timer_get_unique_id(); t311 = mac_timers->timer_get_unique_id(); @@ -930,6 +931,13 @@ void rrc::timer_expired(uint32_t timeout_id) { } else if (timeout_id == t311) { rrc_log->info("Timer T311 expired: Going to RRC IDLE\n"); state = RRC_STATE_LEAVE_CONNECTED; + } else if (timeout_id == t300) { + rrc_log->info("Timer T300 expired: ConnectionRequest failed. Reset MAC and restablished RLC.\n"); + rlc->reestablish(); + mac->reset(); + set_mac_default(); + state = RRC_STATE_IDLE; + nas->plmn_search_end(); } else if (timeout_id == t301) { if (state == RRC_STATE_IDLE) { rrc_log->info("Timer T301 expired: Already in IDLE.\n"); @@ -985,6 +993,8 @@ void rrc::send_con_request() { ul_ccch_msg.msg.rrc_con_req.cause = LIBLTE_RRC_CON_REQ_EST_CAUSE_MO_SIGNALLING; + mac_timers->timer_get(t300)->reset(); + mac_timers->timer_get(t300)->run(); send_ul_ccch_msg(); } @@ -1676,6 +1686,8 @@ void rrc::parse_dl_ccch(byte_buffer_t *pdu) { case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_REJ: rrc_log->info("Connection Reject received. Wait time: %d\n", dl_ccch_msg.msg.rrc_con_rej.wait_time); + // Stop T300 timer + mac_timers->timer_get(t300)->stop(); state = RRC_STATE_LEAVE_CONNECTED; break; case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_SETUP: @@ -1978,14 +1990,15 @@ void rrc::apply_sib2_configs(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2) { liblte_rrc_srs_subfr_config_num[sib2->rr_config_common_sib.srs_ul_cnfg.subfr_cnfg], sib2->rr_config_common_sib.srs_ul_cnfg.ack_nack_simul_tx ? "yes" : "no"); + mac_timers->timer_get(t300)->set(this, liblte_rrc_t300_num[sib2->ue_timers_and_constants.t300]); mac_timers->timer_get(t301)->set(this, liblte_rrc_t301_num[sib2->ue_timers_and_constants.t301]); mac_timers->timer_get(t310)->set(this, liblte_rrc_t310_num[sib2->ue_timers_and_constants.t310]); mac_timers->timer_get(t311)->set(this, liblte_rrc_t311_num[sib2->ue_timers_and_constants.t311]); N310 = liblte_rrc_n310_num[sib2->ue_timers_and_constants.n310]; N311 = liblte_rrc_n311_num[sib2->ue_timers_and_constants.n311]; - rrc_log->info("Set Constants and Timers: N310=%d, N311=%d, t301=%d, t310=%d, t311=%d\n", - N310, N311, mac_timers->timer_get(t301)->get_timeout(), + rrc_log->info("Set Constants and Timers: N310=%d, N311=%d, t300=%d, t301=%d, t310=%d, t311=%d\n", + N310, N311, mac_timers->timer_get(t300)->get_timeout(), mac_timers->timer_get(t301)->get_timeout(), mac_timers->timer_get(t310)->get_timeout(), mac_timers->timer_get(t311)->get_timeout()); } @@ -2222,6 +2235,10 @@ void rrc::apply_rr_config_dedicated(LIBLTE_RRC_RR_CONFIG_DEDICATED_STRUCT *cnfg) } void rrc::handle_con_setup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *setup) { + + // Stop T300 timer + mac_timers->timer_get(t300)->stop(); + // Apply the Radio Resource configuration apply_rr_config_dedicated(&setup->rr_cnfg); } From be09457ccb6d27f42e3359b9c0610a2155647359 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 12 Mar 2018 16:18:32 +0000 Subject: [PATCH 253/342] Starting to make sure that UL S1-U fteid and S11 SGW ctr fteid are kept, even when UE context release is called. --- srsepc/hdr/mme/s1ap_common.h | 19 +---- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 16 ++-- srsepc/src/mme/s1ap_nas_transport.cc | 112 ++++++++++++++++---------- 3 files changed, 83 insertions(+), 64 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index 7ffaf3434..5bb60e5a6 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -82,6 +82,7 @@ enum erab_state ERAB_ACTIVE }; + typedef struct{ uint8_t mme_code; uint16_t mme_group; @@ -139,9 +140,7 @@ typedef struct{ emm_state_t state; uint32_t mme_ue_s1ap_id; uint8_t attach_type; - //enum nas_init_msg init_msg; - //enum emm_connection_management conn_mngmnt_state; - //enum emm_common_proc common_proc_state; + srslte::gtpc_f_teid_ie sgw_ctrl_fteid; } ue_emm_ctx_t; typedef struct{ @@ -150,24 +149,14 @@ typedef struct{ uint32_t mme_ue_s1ap_id; struct sctp_sndrcvinfo enb_sri; ecm_state_t state; - srslte::gtpc_f_teid_ie sgw_ctrl_fteid; erab_ctx_t erabs_ctx[MAX_ERABS_PER_UE]; bool eit; } ue_ecm_ctx_t; typedef struct{ - uint64_t imsi; - uint32_t enb_ue_s1ap_id; - uint32_t mme_ue_s1ap_id; - uint16_t enb_id; - struct sctp_sndrcvinfo enb_sri; - emm_state_t emm_state; - eps_security_ctx_t security_ctxt; - erab_ctx_t erabs_ctx[MAX_ERABS_PER_UE]; - bool eit; - uint8_t procedure_transaction_id; - uint8_t attach_type; + ue_emm_ctx_t emm_ctx; + ue_ecm_ctx_t ecm_ctx; } ue_ctx_t; }//namespace #endif diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index eacccb5c7..34e0c8db3 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -216,8 +216,8 @@ s1ap_ctx_mngmt_proc::handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_I { m_s1ap_log->error("Could not find UE's EMM context in active UE's map\n"); return false; - } - + } + m_s1ap_log->console("Received Initial Context Setup Response\n"); //Setup E-RABs for(uint32_t i=0; iE_RABSetupListCtxtSURes.len;i++) { @@ -250,8 +250,10 @@ s1ap_ctx_mngmt_proc::handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_I m_s1ap_log->console("E-RAB Context -- eNB TEID 0x%x; eNB GTP-U Address %s\n", erab_ctx->enb_fteid.teid, enb_addr_str); } - if(emm_ctx->state == EMM_STATE_DEREGISTERED) + if(emm_ctx->state == EMM_STATE_REGISTERED) { + m_s1ap_log->console("Initial Context Setup Response triggered from Service Request.\n"); + m_s1ap_log->console("Sending Modify Bearer Request.\n"); m_mme_gtpc->send_modify_bearer_request(ue_ecm_ctx->imsi, &ue_ecm_ctx->erabs_ctx[5]); } return true; @@ -279,6 +281,8 @@ s1ap_ctx_mngmt_proc::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECON if (ecm_ctx->state == ECM_STATE_CONNECTED) { //There are active E-RABs, send release access mearers request + m_s1ap_log->console("There are active E-RABs, send release access mearers request"); + m_s1ap_log->info("There are active E-RABs, send release access mearers request"); m_mme_gtpc->send_release_access_bearers_request(ecm_ctx->imsi); } else @@ -293,8 +297,10 @@ s1ap_ctx_mngmt_proc::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECON ecm_ctx->erabs_ctx[i].state = ERAB_DEACTIVATED; } //Delete UE context - m_s1ap->delete_ue_ecm_ctx(ecm_ctx->mme_ue_s1ap_id); - m_s1ap_log->info("Deleted UE ECM Context.\n"); + ecm_ctx->state = ECM_STATE_DISCONNECTED; + ecm_ctx->mme_ue_s1ap_id = 0; + m_s1ap_log->info("UE ECM Disconnected.\n"); + m_s1ap_log->console("Deleted UE ECM Context.\n"); return true; } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index fb464c26f..2227cddda 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -492,6 +492,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, //Set tmp UE EMM context tmp_ue_emm_ctx.imsi = 0; + tmp_ue_emm_ctx.state = EMM_STATE_DEREGISTERED; //Save UE network capabilities memcpy(&tmp_ue_emm_ctx.security_ctxt.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT)); @@ -570,6 +571,8 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, //Create new MME UE S1AP Identity ue_emm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + //Set EMM as de-registered + ue_emm_ctx->state = EMM_STATE_DEREGISTERED; //Save Attach type ue_emm_ctx->attach_type = attach_req.eps_attach_type; //Create UE ECM context @@ -602,7 +605,9 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, //NAS integrity failed. Re-start authentication process. m_s1ap_log->console("GUTI Attach request NAS integrity failed.\n"); m_s1ap_log->console("RE-starting authentication procedure.\n"); - //FIXME + //pack_identity_request(); + //(srslte::byte_buffer_t *reply_msg, uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id) + return true; } } else @@ -660,61 +665,80 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, m_s1ap_log->console("Service Request -- Short MAC valid\n"); m_s1ap_log->info("Service Request -- Short MAC valid\n"); ue_ecm_ctx_t *ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(emm_ctx->mme_ue_s1ap_id); - if(ecm_ctx !=NULL) + if(ecm_ctx == NULL) { - //Service request to Connected UE. - //Set eNB UE S1ap identity - ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; - m_s1ap_log->console("Service Request -- eNB UE S1AP Id %d \n", enb_ue_s1ap_id); - m_s1ap_log->info("Service Request -- eNB UE S1AP Id %d\n ", enb_ue_s1ap_id); - - //Delete eNB context and connect. - m_s1ap_log->console("Service Request -- User has ECM context already\n"); - m_s1ap_log->info("Service Request -- User has ECM context already\n"); - m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); - //int default_bearer_id = 5; - //m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[default_bearer_id]); + m_s1ap_log->console("UE ECM context is not initialized.\n"); + m_s1ap_log->error("UE ECM context is not initialized.\n"); + pack_service_reject(reply_buffer, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED, enb_ue_s1ap_id); + *reply_flag = true; + return true; } else { - ue_ecm_ctx_t ue_ecm_ctx; - ue_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; - - //UE not connect. Connect normally. - m_s1ap_log->console("Service Request -- User without ECM context\n"); - m_s1ap_log->info("Service Request -- User without ECM context\n"); - //Create ECM context - ue_ecm_ctx.imsi = emm_ctx->imsi; - ue_ecm_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); - emm_ctx->mme_ue_s1ap_id = ue_ecm_ctx.mme_ue_s1ap_id; - //Set eNB information - ue_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; - memcpy(&ue_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); - - //Save whether secure ESM information transfer is necessary - ue_ecm_ctx.eit = false; - - //Initialize E-RABs - for(uint i = 0 ; i< MAX_ERABS_PER_UE; i++) + if(ecm_ctx->state == ECM_STATE_CONNECTED) + { + m_s1ap_log->error("Service Request -- User is ECM CONNECTED\n"); + + //Service request to Connected UE. + //Set eNB UE S1ap identity + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + m_s1ap_log->console("Service Request -- eNB UE S1AP Id %d \n", enb_ue_s1ap_id); + m_s1ap_log->info("Service Request -- eNB UE S1AP Id %d\n ", enb_ue_s1ap_id); + + //Delete eNB context and connect. + m_s1ap_log->console("Service Request -- User has ECM context already\n"); + m_s1ap_log->info("Service Request -- User has ECM context already\n"); + m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); + //int default_bearer_id = 5; + //m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[default_bearer_id]); + //FIXME Send Modify context request OR send ctx release command and wait for the reply. + + } + else if(ecm_ctx->state == ECM_STATE_DISCONNECTED) + { + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + + //UE not connect. Connect normally. + m_s1ap_log->console("Service Request -- User is ECM DISCONNECTED\n"); + m_s1ap_log->info("Service Request -- User is ECM DISCONNECTED\n"); + //Create ECM context + ecm_ctx->imsi = emm_ctx->imsi; + ecm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + emm_ctx->mme_ue_s1ap_id = ecm_ctx->mme_ue_s1ap_id; + //Set eNB information + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + memcpy(&ecm_ctx->enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + + //Save whether secure ESM information transfer is necessary + ecm_ctx->eit = false; + + //Initialize E-RABs + for(uint i = 0 ; i< MAX_ERABS_PER_UE; i++) + { + ue_ecm_ctx.erabs_ctx[i].state = ERAB_DEACTIVATED; + ue_ecm_ctx.erabs_ctx[i].erab_id = i; + } + ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(emm_ctx->mme_ue_s1ap_id); + + //Re-generate K_eNB + liblte_security_generate_k_enb(emm_ctx->security_ctxt.k_asme, emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.k_enb); + m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",emm_ctx->security_ctxt.ul_nas_count); + m_s1ap_log->console("UE Ctr TEID %d\n", emm_ctx->sgw_ctrl_fteid.teid); + m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx,&ecm_ctx->erabs_ctx[5]); + + } + else { - ue_ecm_ctx.erabs_ctx[i].state = ERAB_DEACTIVATED; - ue_ecm_ctx.erabs_ctx[i].erab_id = i; + m_s1ap_log->console("ECM context is un-initialized.\n"); + m_s1ap_log->error("ECM context is un-initialized.\n"); } - memcpy(&ue_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); - m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); - - //Re-generate K_eNB - liblte_security_generate_k_enb(emm_ctx->security_ctxt.k_asme, emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.k_enb); - m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",emm_ctx->security_ctxt.ul_nas_count); - //FIXME Send Modify context request OR send ctx release command and wait for the reply. - m_mme_gtpc->send_create_session_request(ue_ecm_ctx.imsi); - m_s1ap_log->console("UE ESM Ctr TEID %d\n", ue_ecm_ctx.sgw_ctrl_fteid.teid); } } else { m_s1ap_log->console("Service Request -- Short MAC invalid. Re-starting authentication procedure \n"); m_s1ap_log->console("Service Request -- Short MAC invalid. Re-starting authentication procedure \n"); + m_s1ap_log->console("Authentication procedure is not restarted yet!\n"); } return true; } From 8bda956330794a96e407394f7275e5652762fa57 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 13 Mar 2018 01:01:53 +0100 Subject: [PATCH 254/342] Solved logging error trace --- srsue/src/phy/phch_worker.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 8a6c5cd8b..12e717b9a 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -574,7 +574,7 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) last_dl_pdcch_ncce = srslte_ue_dl_get_ncce(&ue_dl); - char hexstr[16]; + char hexstr[SRSLTE_DCI_MAX_BITS/8]; hexstr[0]='\0'; if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { srslte_vec_sprint_hex(hexstr, sizeof(hexstr), dci_msg.data, dci_msg.nof_bits); @@ -812,7 +812,7 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant) grant->has_cqi_request = dci_unpacked.cqi_request; ret = true; - char hexstr[16]; + char hexstr[SRSLTE_DCI_MAX_BITS/8]; hexstr[0]='\0'; if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { srslte_vec_sprint_hex(hexstr, sizeof(hexstr), dci_msg.data, dci_msg.nof_bits); From c2098ad6260ee3c772c26f404314fe01c4bc5f18 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Mar 2018 18:52:21 +0100 Subject: [PATCH 255/342] Removed unused sample offset correction --- lib/include/srslte/interfaces/ue_interfaces.h | 3 +- lib/include/srslte/phy/ue/ue_dl.h | 7 ----- lib/src/phy/ue/ue_dl.c | 30 +------------------ srsue/hdr/phy/phch_worker.h | 3 +- srsue/src/main.cc | 4 --- srsue/src/phy/phch_recv.cc | 2 -- srsue/src/phy/phch_worker.cc | 8 ----- srsue/src/phy/phy.cc | 3 +- 8 files changed, 4 insertions(+), 56 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 75acc27ea..9a7a68a34 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -487,8 +487,7 @@ typedef struct { uint32_t cfo_ref_mask; bool average_subframe_enabled; int time_correct_period; - bool sfo_correct_disable; - std::string sss_algorithm; + std::string sss_algorithm; float estimator_fil_w; bool rssi_sensor_enabled; bool sic_pss_enabled; diff --git a/lib/include/srslte/phy/ue/ue_dl.h b/lib/include/srslte/phy/ue/ue_dl.h index 6974a0b99..c5b0da52a 100644 --- a/lib/include/srslte/phy/ue/ue_dl.h +++ b/lib/include/srslte/phy/ue/ue_dl.h @@ -84,8 +84,6 @@ typedef struct SRSLTE_API { srslte_ofdm_t fft_mbsfn; srslte_chest_dl_t chest; - srslte_cfo_t sfo_correct; - srslte_pdsch_cfg_t pdsch_cfg; srslte_pdsch_cfg_t pmch_cfg; srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_CODEWORDS]; @@ -126,8 +124,6 @@ typedef struct SRSLTE_API { srslte_dci_msg_t pending_ul_dci_msg; uint16_t pending_ul_dci_rnti; - float sample_offset; - float last_phich_corr; }srslte_ue_dl_t; @@ -195,9 +191,6 @@ SRSLTE_API int srslte_ue_dl_find_dl_dci_type(srslte_ue_dl_t *q, SRSLTE_API uint32_t srslte_ue_dl_get_ncce(srslte_ue_dl_t *q); -SRSLTE_API void srslte_ue_dl_set_sample_offset(srslte_ue_dl_t * q, - float sample_offset); - SRSLTE_API int srslte_ue_dl_decode(srslte_ue_dl_t *q, uint8_t *data[SRSLTE_MAX_CODEWORDS], uint32_t tm, diff --git a/lib/src/phy/ue/ue_dl.c b/lib/src/phy/ue/ue_dl.c index 3815041a7..98ff5c9fd 100644 --- a/lib/src/phy/ue/ue_dl.c +++ b/lib/src/phy/ue/ue_dl.c @@ -71,7 +71,6 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q, q->pmch_pkt_errors = 0; q->pmch_pkts_total = 0; q->pending_ul_dci_rnti = 0; - q->sample_offset = 0; q->nof_rx_antennas = nof_rx_antennas; for (int j = 0; j < SRSLTE_MAX_PORTS; j++) { @@ -147,12 +146,7 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q, goto clean_exit; } } - if (srslte_cfo_init(&q->sfo_correct, max_prb*SRSLTE_NRE)) { - fprintf(stderr, "Error initiating SFO correct\n"); - goto clean_exit; - } - srslte_cfo_set_tol(&q->sfo_correct, 1e-5f/q->fft[0].symbol_sz); - + ret = SRSLTE_SUCCESS; } else { fprintf(stderr, "Invalid parametres\n"); @@ -178,7 +172,6 @@ void srslte_ue_dl_free(srslte_ue_dl_t *q) { srslte_pdcch_free(&q->pdcch); srslte_pdsch_free(&q->pdsch); srslte_pmch_free(&q->pmch); - srslte_cfo_free(&q->sfo_correct); for (int i = 0; i < SRSLTE_MAX_TB; i++) { srslte_softbuffer_rx_free(q->softbuffers[i]); if (q->softbuffers[i]) { @@ -209,7 +202,6 @@ int srslte_ue_dl_set_cell(srslte_ue_dl_t *q, srslte_cell_t cell) q->pkt_errors = 0; q->pkts_total = 0; q->pending_ul_dci_rnti = 0; - q->sample_offset = 0; if (q->cell.id != cell.id || q->cell.nof_prb == 0) { if (q->cell.nof_prb != 0) { @@ -220,11 +212,6 @@ int srslte_ue_dl_set_cell(srslte_ue_dl_t *q, srslte_cell_t cell) fprintf(stderr, "Error resizing REGs\n"); return SRSLTE_ERROR; } - if (srslte_cfo_resize(&q->sfo_correct, q->cell.nof_prb*SRSLTE_NRE)) { - fprintf(stderr, "Error resizing SFO correct\n"); - return SRSLTE_ERROR; - } - srslte_cfo_set_tol(&q->sfo_correct, 1e-5f/q->fft[0].symbol_sz); for (int port = 0; port < q->nof_rx_antennas; port++) { if (srslte_ofdm_rx_set_prb(&q->fft[port], q->cell.cp, q->cell.nof_prb)) { fprintf(stderr, "Error resizing FFT\n"); @@ -348,10 +335,6 @@ void srslte_ue_dl_reset(srslte_ue_dl_t *q) { bzero(&q->pdsch_cfg, sizeof(srslte_pdsch_cfg_t)); } -void srslte_ue_dl_set_sample_offset(srslte_ue_dl_t * q, float sample_offset) { - q->sample_offset = sample_offset; -} - /** Applies the following operations to a subframe of synchronized samples: * - OFDM demodulation * - Channel estimation @@ -395,17 +378,6 @@ int srslte_ue_dl_decode_fft_estimate_noguru(srslte_ue_dl_t *q, cf_t *input[SRSLT /* Run FFT for all subframe data */ for (int j=0;jnof_rx_antennas;j++) { srslte_ofdm_rx_sf_ng(&q->fft[j], input[j], q->sf_symbols_m[j]); - - /* Correct SFO multiplying by complex exponential in the time domain */ - if (q->sample_offset) { - int nsym = SRSLTE_CP_NSYMB(q->cell.cp); - for (int i=0;i<2*nsym;i++) { - srslte_cfo_correct(&q->sfo_correct, - &q->sf_symbols_m[j][i*q->cell.nof_prb*SRSLTE_NRE], - &q->sf_symbols_m[j][i*q->cell.nof_prb*SRSLTE_NRE], - q->sample_offset / q->fft[j].symbol_sz); - } - } } return srslte_ue_dl_decode_estimate_mbsfn(q, sf_idx, cfi, SRSLTE_SF_NORM); } else { diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index 167334918..6f72285b2 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -54,8 +54,7 @@ public: void set_tti(uint32_t tti, uint32_t tx_tti); void set_tx_time(srslte_timestamp_t tx_time, uint32_t next_offset); void set_cfo(float cfo); - void set_sample_offset(float sample_offset); - + void set_ul_params(bool pregen_disabled = false); void set_crnti(uint16_t rnti); void enable_pregen_signals(bool enabled); diff --git a/srsue/src/main.cc b/srsue/src/main.cc index f5df0af2d..d2d029c63 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -258,10 +258,6 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { bpo::value(&args->expert.phy.time_correct_period)->default_value(5), "Period for sampling time offset correction.") - ("expert.sfo_correct_disable", - bpo::value(&args->expert.phy.sfo_correct_disable)->default_value(false), - "Disables phase correction before channel estimation.") - ("expert.sss_algorithm", bpo::value(&args->expert.phy.sss_algorithm)->default_value("full"), "Selects the SSS estimation algorithm.") diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index a96b9c545..850294175 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -636,8 +636,6 @@ void phch_recv::run_thread() worker->set_cfo(ul_dl_factor * metrics.cfo / 15000); worker_com->set_sync_metrics(metrics); - worker->set_sample_offset(srslte_ue_sync_get_sfo(&ue_sync)/1000); - /* Compute TX time: Any transmission happens in TTI+4 thus advance 4 ms the reception time */ srslte_timestamp_t rx_time, tx_time, tx_time_prach; srslte_ue_sync_get_last_timestamp(&ue_sync, &rx_time); diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 8a6c5cd8b..32f336f59 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -190,14 +190,6 @@ void phch_worker::set_cfo(float cfo_) cfo = cfo_; } -void phch_worker::set_sample_offset(float sample_offset) -{ - if (phy->args->sfo_correct_disable) { - sample_offset = 0; - } - srslte_ue_dl_set_sample_offset(&ue_dl, sample_offset); -} - void phch_worker::set_crnti(uint16_t rnti) { srslte_ue_dl_set_rnti(&ue_dl, rnti); diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 5c69d567d..27b389a4e 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -97,8 +97,7 @@ void phy::set_default_args(phy_args_t *args) args->cfo_integer_enabled = false; args->cfo_correct_tol_hz = 50; args->time_correct_period = 5; - args->sfo_correct_disable = false; - args->sss_algorithm = "full"; + args->sss_algorithm = "full"; args->estimator_fil_w = 0.1; } From 809c550ca2dd0ebae0e1632abc3330004b2c5e2e Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Mar 2018 19:07:15 +0100 Subject: [PATCH 256/342] Use RS power estimation for serving cell RSRP/SNR measurements. Use correlation of RS sequences for neighbour cell verification of Cell ID --- .../srslte/phy/ch_estimation/chest_dl.h | 10 ++- lib/src/phy/ch_estimation/chest_dl.c | 42 +++++++++-- srsue/hdr/phy/phch_recv.h | 3 +- srsue/src/phy/phch_recv.cc | 72 ++++++++++++------- 4 files changed, 96 insertions(+), 31 deletions(-) diff --git a/lib/include/srslte/phy/ch_estimation/chest_dl.h b/lib/include/srslte/phy/ch_estimation/chest_dl.h index c1f5579a1..e7cc28bed 100644 --- a/lib/include/srslte/phy/ch_estimation/chest_dl.h +++ b/lib/include/srslte/phy/ch_estimation/chest_dl.h @@ -82,10 +82,13 @@ typedef struct { srslte_interp_lin_t srslte_interp_lin_3; srslte_interp_lin_t srslte_interp_lin_mbsfn; float rssi[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; - float rsrp[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; + float rsrp[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; + float rsrp_corr[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; float noise_estimate[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; float cfo; + bool rsrp_neighbour; + bool cfo_estimate_enable; uint32_t cfo_estimate_sf_mask; @@ -158,6 +161,9 @@ SRSLTE_API void srslte_chest_dl_cfo_estimate_enable(srslte_chest_dl_t *q, SRSLTE_API void srslte_chest_dl_average_subframe(srslte_chest_dl_t *q, bool enable); +SRSLTE_API void srslte_chest_dl_set_rsrp_neighbour(srslte_chest_dl_t *q, + bool rsrp_for_neighbour); + SRSLTE_API float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q); SRSLTE_API float srslte_chest_dl_get_cfo(srslte_chest_dl_t *q); @@ -185,4 +191,6 @@ SRSLTE_API float srslte_chest_dl_get_rsrp_port(srslte_chest_dl_t *q, SRSLTE_API float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q); +SRSLTE_API float srslte_chest_dl_get_rsrp_neighbour(srslte_chest_dl_t *q); + #endif diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index ec827ec13..8d9125910 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -152,7 +152,9 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, uint32_t max_prb) } q->noise_alg = SRSLTE_NOISE_ALG_REFS; - + + q->rsrp_neighbour = false; + q->smooth_filter_len = 3; srslte_chest_dl_set_smooth_filter3_coeff(q, 0.1); @@ -545,7 +547,7 @@ void chest_interpolate_noise_est(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, ui } } -int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id) +int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id) { uint32_t npilots = SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id); @@ -557,14 +559,18 @@ int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, u q->pilot_estimates, npilots); /* Compute RSRP for the channel estimates in this port */ - double energy = cabs(srslte_vec_acc_cc(q->pilot_estimates, npilots)/npilots); - q->rsrp[rxant_id][port_id] = energy*energy; + if (q->rsrp_neighbour) { + double energy = cabs(srslte_vec_acc_cc(q->pilot_estimates, npilots)/npilots); + q->rsrp_corr[rxant_id][port_id] = energy*energy; + } + q->rsrp[rxant_id][port_id] = srslte_vec_avg_power_cf(q->pilot_recv_signal, npilots); q->rssi[rxant_id][port_id] = srslte_chest_dl_rssi(q, input, port_id); chest_interpolate_noise_est(q, input, ce, sf_idx, port_id, rxant_id, SRSLTE_SF_NORM); return 0; } + int srslte_chest_dl_estimate_port_mbsfn(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id, uint16_t mbsfn_area_id) { @@ -623,6 +629,10 @@ int srslte_chest_dl_estimate_multi_mbsfn(srslte_chest_dl_t *q, cf_t *input[SRSLT return SRSLTE_SUCCESS; } +void srslte_chest_dl_set_rsrp_neighbour(srslte_chest_dl_t *q, bool rsrp_for_neighbour) { + q->rsrp_neighbour = rsrp_for_neighbour; +} + void srslte_chest_dl_average_subframe(srslte_chest_dl_t *q, bool enable) { q->average_subframe = enable; @@ -710,6 +720,19 @@ float srslte_chest_dl_get_rsrp_port(srslte_chest_dl_t *q, uint32_t port) { return sum; } +float srslte_chest_dl_get_rsrp_neighbour_port(srslte_chest_dl_t *q, uint32_t port) { + float sum = 0.0f; + for (int j = 0; j < q->cell.nof_ports; ++j) { + sum +=q->rsrp_corr[port][j]; + } + + if (q->cell.nof_ports) { + sum /= q->cell.nof_ports; + } + + return sum; +} + float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) { float max = -0.0f; for (int i = 0; i < q->last_nof_antennas; ++i) { @@ -720,3 +743,14 @@ float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) { } return max; } + +float srslte_chest_dl_get_rsrp_neighbour(srslte_chest_dl_t *q) { + float max = -0.0f; + for (int i = 0; i < q->last_nof_antennas; ++i) { + float v = srslte_chest_dl_get_rsrp_neighbour_port(q, i); + if (v > max) { + max = v; + } + } + return max; +} diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index 7a04e4b10..3d00b631b 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -171,6 +171,7 @@ private: ret_code run_multiple_subframes(cf_t *buffer, uint32_t offset, uint32_t sf_idx, uint32_t nof_sf); float rssi(); float rsrp(); + float rsrp_n(); float rsrq(); float snr(); uint32_t frame_st_idx(); @@ -183,7 +184,7 @@ private: uint32_t nof_subframes; uint32_t current_prb; float rx_gain_offset; - float mean_rsrp, mean_rsrq, mean_snr, mean_rssi; + float mean_rsrp, mean_rsrp_n, mean_rsrq, mean_snr, mean_rssi; uint32_t final_offset; const static int RSRP_MEASURE_NOF_FRAMES = 5; }; diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 850294175..6ec87d2fa 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1022,6 +1022,7 @@ void phch_recv::measure::init(cf_t *buffer[SRSLTE_MAX_PORTS], srslte::log *log_h Error("SYNC: Initiating ue_dl_measure\n"); return; } + srslte_chest_dl_set_rsrp_neighbour(&ue_dl.chest, true); reset(); } @@ -1054,6 +1055,10 @@ float phch_recv::measure::rsrp() { return 10*log10(mean_rsrp) + 30 - rx_gain_offset; } +float phch_recv::measure::rsrp_n() { + return 10*log10(mean_rsrp_n) + 30 - rx_gain_offset; +} + float phch_recv::measure::rsrq() { return 10*log10(mean_rsrq); } @@ -1099,12 +1104,13 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in sf_idx ++; } + + // Fine-tune offset using RS +#ifdef FINE_TUNE_OFFSET_WITH_RS float max_rsrp = -200; int best_test_offset = 0; int test_offset = 0; bool found_best = false; - - // Fine-tune offset using RS for (uint32_t n=0;n<5;n++) { test_offset = offset-2+n; @@ -1128,11 +1134,14 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in } } + Debug("INTRA: fine-tuning offset: %d, found_best=%d, rem_sf=%d\n", offset, found_best, nof_sf); + offset = found_best?best_test_offset:offset; +#endif + if (offset >= 0 && offset < sf_len*max_sf) { uint32_t nof_sf = (sf_len*max_sf - offset)/sf_len; - Debug("INTRA: fine-tuning offset: %d, found_best=%d, rem_sf=%d\n", offset, found_best, nof_sf); final_offset = offset; @@ -1161,25 +1170,28 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx) } float rsrp = srslte_chest_dl_get_rsrp(&ue_dl.chest); + float rsrp_n = srslte_chest_dl_get_rsrp_neighbour(&ue_dl.chest); float rsrq = srslte_chest_dl_get_rsrq(&ue_dl.chest); float snr = srslte_chest_dl_get_snr(&ue_dl.chest); float rssi = srslte_vec_avg_power_cf(buffer[0], SRSLTE_SF_LEN_PRB(current_prb)); if (cnt == 0) { - mean_rsrp = rsrp; - mean_rsrq = rsrq; - mean_snr = snr; - mean_rssi = rssi; + mean_rsrp = rsrp; + mean_rsrp_n = rsrp_n; + mean_rsrq = rsrq; + mean_snr = snr; + mean_rssi = rssi; } else { - mean_rsrp = SRSLTE_VEC_CMA(rsrp, mean_rsrp, cnt); - mean_rsrq = SRSLTE_VEC_CMA(rsrq, mean_rsrq, cnt); - mean_snr = SRSLTE_VEC_CMA(snr, mean_snr, cnt); - mean_rssi = SRSLTE_VEC_CMA(rssi, mean_rssi, cnt); + mean_rsrp = SRSLTE_VEC_CMA(rsrp, mean_rsrp, cnt); + mean_rsrp_n = SRSLTE_VEC_CMA(rsrp_n, mean_rsrp_n, cnt); + mean_rsrq = SRSLTE_VEC_CMA(rsrq, mean_rsrq, cnt); + mean_snr = SRSLTE_VEC_CMA(snr, mean_snr, cnt); + mean_rssi = SRSLTE_VEC_CMA(rssi, mean_rssi, cnt); } cnt++; - log_h->debug("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm, SNR=%.1f dB\n", - cnt, nof_subframes, sf_idx, rsrp, snr); + log_h->debug("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm, corr-RSRP=%.1f dBm, SNR=%.1f dB\n", + cnt, nof_subframes, sf_idx, rsrp, rsrp_n, snr); if (cnt >= nof_subframes) { return MEASURE_OK; @@ -1217,6 +1229,7 @@ void phch_recv::scell_recv::init(srslte::log *log_h, bool sic_pss_enabled, uint3 fprintf(stderr, "Error initiating sync_find\n"); return; } + srslte_sync_set_sss_algorithm(&sync_find, SSS_FULL); srslte_sync_cp_en(&sync_find, false); srslte_sync_set_cfo_pss_enable(&sync_find, true); srslte_sync_set_threshold(&sync_find, 1.7); @@ -1230,8 +1243,7 @@ void phch_recv::scell_recv::init(srslte::log *log_h, bool sic_pss_enabled, uint3 srslte_sync_set_sss_eq_enable(&sync_find, true); sync_find.pss.chest_on_filter = true; - - sync_find.sss_channel_equalize = true; + sync_find.sss_channel_equalize = false; reset(); } @@ -1336,17 +1348,27 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset, case measure::MEASURE_OK: // Consider a cell to be detectable 8.1.2.2.1.1 from 36.133. Currently only using first condition if (measure_p.rsrp() > ABSOLUTE_RSRP_THRESHOLD_DBM) { - cells[nof_cells].pci = found_cell.id; - cells[nof_cells].rsrp = measure_p.rsrp(); - cells[nof_cells].rsrq = measure_p.rsrq(); - cells[nof_cells].offset = measure_p.frame_st_idx(); - - Info( - "INTRA: Found neighbour cell %d: PCI=%03d, RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f, sf=%d, max_sf=%d, n_id_2=%d, CFO=%6.1f Hz\n", - nof_cells, cell_id, measure_p.rsrp(), measure_p.frame_st_idx(), sync_find.peak_value, - sf_idx, max_sf5, n_id_2, 15000 * srslte_sync_get_cfo(&sync_find)); - nof_cells++; + // Check the cell id has been correctly identified by using the correlation of the RS sequences + // By experimentation, typically the cross-correlation is ~3/4 dB less + if (measure_p.rsrp_n() > measure_p.rsrp() - 6) { + cells[nof_cells].pci = found_cell.id; + cells[nof_cells].rsrp = measure_p.rsrp(); + cells[nof_cells].rsrq = measure_p.rsrq(); + cells[nof_cells].offset = measure_p.frame_st_idx(); + + Info( + "INTRA: Found neighbour cell %d: PCI=%03d, RSRP=%5.1f dBm, corr-RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f, sf=%d, max_sf=%d, n_id_2=%d, CFO=%6.1f Hz\n", + nof_cells, cell_id, measure_p.rsrp(), measure_p.rsrp_n(), measure_p.frame_st_idx(), sync_find.peak_value, + sf_idx, max_sf5, n_id_2, 15000 * srslte_sync_get_cfo(&sync_find)); + + nof_cells++; + } else { + Info( + "INTRA: Found phantom cell %d: PCI=%03d, RSRP=%5.1f dBm, corr-RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f, sf=%d, max_sf=%d, n_id_2=%d, CFO=%6.1f Hz\n", + nof_cells, cell_id, measure_p.rsrp(), measure_p.rsrp_n(), measure_p.frame_st_idx(), sync_find.peak_value, + sf_idx, max_sf5, n_id_2, 15000 * srslte_sync_get_cfo(&sync_find)); + } /* if (sic_pss_enabled) { From b77e3b0be56114958eda79747ab5be0f63c0db5d Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Mar 2018 20:01:09 +0100 Subject: [PATCH 257/342] Avoid negative offset in neighbour cell search --- srsue/src/phy/phch_recv.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 6ec87d2fa..b186e0ae1 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1099,7 +1099,7 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in ret_code ret = IDLE; offset = offset-sf_len/2; - if (offset < 0) { + while (offset < 0) { offset += sf_len; sf_idx ++; } From 0fbeee72a17ce420a0036f2680e530a97a469517 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Mar 2018 20:47:31 +0100 Subject: [PATCH 258/342] Fixed offset int in previous commit --- srsue/hdr/phy/phch_recv.h | 2 +- srsue/src/phy/phch_recv.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index 3d00b631b..8b87f0521 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -168,7 +168,7 @@ private: void set_cell(srslte_cell_t cell); ret_code run_subframe(uint32_t sf_idx); ret_code run_subframe_sync(srslte_ue_sync_t *ue_sync, uint32_t sf_idx); - ret_code run_multiple_subframes(cf_t *buffer, uint32_t offset, uint32_t sf_idx, uint32_t nof_sf); + ret_code run_multiple_subframes(cf_t *buffer, int offset, uint32_t sf_idx, uint32_t nof_sf); float rssi(); float rsrp(); float rsrp_n(); diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index b186e0ae1..2799cb999 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1090,7 +1090,7 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe_sync(srslte_ue_syn } phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *input_buffer, - uint32_t offset, + int offset, uint32_t sf_idx, uint32_t max_sf) { @@ -1099,7 +1099,7 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in ret_code ret = IDLE; offset = offset-sf_len/2; - while (offset < 0) { + while (offset < 0 && sf_idx < max_sf) { offset += sf_len; sf_idx ++; } From 33ebde5387ce652d39bc7506400c05ae129018cc Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 09:53:48 +0100 Subject: [PATCH 259/342] Fixed bug SIB3 loop and window_start 10s wait in disconnect --- srsue/src/phy/phch_recv.cc | 2 +- srsue/src/upper/rrc.cc | 33 +++++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 2799cb999..9d539a02d 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1139,7 +1139,7 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in offset = found_best?best_test_offset:offset; #endif - if (offset >= 0 && offset < sf_len*max_sf) { + if (offset >= 0 && offset < (int) sf_len*max_sf) { uint32_t nof_sf = (sf_len*max_sf - offset)/sf_len; diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 1f0c6eb94..8c346bfaa 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -98,6 +98,7 @@ void rrc::init(phy_interface_rrc *phy_, mac_timers = mac_timers_; state = RRC_STATE_IDLE; si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; ho_syncing = false; @@ -178,10 +179,6 @@ void rrc::run_thread() { while (thread_running) { - if (state >= RRC_STATE_IDLE && state < RRC_STATE_CONNECTING) { - run_si_acquisition_procedure(); - } - switch(state) { /* Procedures in IDLE state 36.304 Sec 4 */ case RRC_STATE_IDLE: @@ -232,13 +229,16 @@ void rrc::run_thread() { si_acquire_state = SI_ACQUIRE_SIB2; } else { apply_sib2_configs(serving_cell->sib2ptr()); - si_acquire_state = SI_ACQUIRE_IDLE; state = RRC_STATE_CELL_SELECTED; } + run_si_acquisition_procedure(); } break; case RRC_STATE_CELL_SELECTED: + si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; + /* The cell is selected when the SIBs are received and applied. * If we were in RRC_CONNECTED and arrive here it means a RLF occurred and we are in Reestablishment procedure. * If T311 is running means there is a reestablishment in progress, send ConnectionReestablishmentRequest. @@ -267,6 +267,8 @@ void rrc::run_thread() { if (connecting_timeout >= RRC_CONNECTING_TIMEOUT) { // Select another cell rrc_log->info("RRC Connecting: timeout expired. Selecting next cell\n"); + si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; state = RRC_STATE_CELL_SELECTING; } break; @@ -358,6 +360,7 @@ void rrc::run_si_acquisition_procedure() if (state == RRC_STATE_CELL_SELECTING) { select_next_cell_in_plmn(); si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; } else if (state == RRC_STATE_PLMN_SELECTION) { phy->cell_search_next(); } @@ -384,13 +387,14 @@ void rrc::run_si_acquisition_procedure() last_win_start = si_win_start; mac->bcch_start_rx(si_win_start, si_win_len); - rrc_log->debug("Instructed MAC to search for system info, win_start=%d, win_len=%d\n", - si_win_start, si_win_len); + rrc_log->info("Instructed MAC to search for system info=%d, win_start=%d, win_len=%d\n", + sysinfo_index, si_win_start, si_win_len); } } else { // We've received all SIBs, move on to connection request si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; state = RRC_STATE_CELL_SELECTED; } break; @@ -477,6 +481,8 @@ void rrc::plmn_select_rrc(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { } } + si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; state = RRC_STATE_CELL_SELECTING; } else { rrc_log->warning("Requested PLMN select in incorrect state %s\n", rrc_state_text[state]); @@ -549,6 +555,8 @@ bool rrc::select_next_cell_in_plmn() { rrc_log->console("Selected cell PCI=%d, EARFCN=%d\n", serving_cell->phy_cell.id, serving_cell->get_earfcn()); phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); + si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; state = RRC_STATE_CELL_SELECTING; return true; } @@ -644,9 +652,7 @@ void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { pthread_mutex_unlock(&mutex); - if (!serving_cell->has_sib1()) { - si_acquire_state = SI_ACQUIRE_SIB1; - } else if (state == RRC_STATE_PLMN_SELECTION) { + if (state == RRC_STATE_PLMN_SELECTION && serving_cell->has_sib1()) { bool ret = false; for (uint32_t j = 0; j < serving_cell->sib1ptr()->N_plmn_ids; j++) { ret |= nas->plmn_found(serving_cell->sib1ptr()->plmn_id[j].id, serving_cell->sib1ptr()->tracking_area_code); @@ -655,6 +661,8 @@ void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { if (!ret) { phy->cell_search_next(); } + } else if (!ho_syncing) { + state = RRC_STATE_CELL_SELECTING; } rrc_log->info("%s %s cell EARFCN=%d, PCI=%d, RSRP=%.1f dBm\n", @@ -1062,6 +1070,8 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause, mac->reset(); set_mac_default(); phy->sync_reset(); + si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; state = RRC_STATE_CELL_SELECTING; } @@ -1347,6 +1357,8 @@ void rrc::leave_connected() { rrc_log->console("RRC IDLE\n"); rrc_log->info("Leaving RRC_CONNECTED state\n"); + si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; drb_up = false; measurements.reset(); pdcp->reset(); @@ -1424,6 +1436,7 @@ void rrc::write_pdu_bcch_dlsch(byte_buffer_t *pdu) { if(serving_cell->has_sib2()) { sysinfo_index++; + rrc_log->info("Increasing sysinfo_index=%d\n", sysinfo_index); } } From c815051238657aa361c76da6916d3bcafa2b708d Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 10:22:44 +0100 Subject: [PATCH 260/342] Increased str buffer for DCI printing --- srsue/src/phy/phch_worker.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 0f2e75920..b3a33ea6c 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -566,7 +566,7 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) last_dl_pdcch_ncce = srslte_ue_dl_get_ncce(&ue_dl); - char hexstr[SRSLTE_DCI_MAX_BITS/8]; + char hexstr[512]; hexstr[0]='\0'; if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { srslte_vec_sprint_hex(hexstr, sizeof(hexstr), dci_msg.data, dci_msg.nof_bits); @@ -804,7 +804,7 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant) grant->has_cqi_request = dci_unpacked.cqi_request; ret = true; - char hexstr[SRSLTE_DCI_MAX_BITS/8]; + char hexstr[512]; hexstr[0]='\0'; if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { srslte_vec_sprint_hex(hexstr, sizeof(hexstr), dci_msg.data, dci_msg.nof_bits); From c0aea5ae13bf89eaa83ff892dc595bdd8446c972 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 10:23:05 +0100 Subject: [PATCH 261/342] Neighbour cell RSRP measurement always and only with correlation method --- lib/src/phy/ch_estimation/chest_dl.c | 4 +-- srsue/hdr/phy/phch_recv.h | 6 ++-- srsue/src/phy/phch_recv.cc | 52 +++++++--------------------- 3 files changed, 17 insertions(+), 45 deletions(-) diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index 8d9125910..e719b22c0 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -734,7 +734,7 @@ float srslte_chest_dl_get_rsrp_neighbour_port(srslte_chest_dl_t *q, uint32_t por } float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) { - float max = -0.0f; + float max = -1e9; for (int i = 0; i < q->last_nof_antennas; ++i) { float v = srslte_chest_dl_get_rsrp_port(q, i); if (v > max) { @@ -745,7 +745,7 @@ float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) { } float srslte_chest_dl_get_rsrp_neighbour(srslte_chest_dl_t *q) { - float max = -0.0f; + float max = -1e9; for (int i = 0; i < q->last_nof_antennas; ++i) { float v = srslte_chest_dl_get_rsrp_neighbour_port(q, i); if (v > max) { diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index 8b87f0521..d71bcb1d5 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -171,7 +171,6 @@ private: ret_code run_multiple_subframes(cf_t *buffer, int offset, uint32_t sf_idx, uint32_t nof_sf); float rssi(); float rsrp(); - float rsrp_n(); float rsrq(); float snr(); uint32_t frame_st_idx(); @@ -184,7 +183,7 @@ private: uint32_t nof_subframes; uint32_t current_prb; float rx_gain_offset; - float mean_rsrp, mean_rsrp_n, mean_rsrq, mean_snr, mean_rssi; + float mean_rsrp, mean_rsrq, mean_snr, mean_rssi; uint32_t final_offset; const static int RSRP_MEASURE_NOF_FRAMES = 5; }; @@ -205,7 +204,6 @@ private: int find_cells(cf_t *input_buffer, float rx_gain_offset, srslte_cell_t current_cell, uint32_t nof_sf, cell_info_t found_cells[MAX_CELLS]); private: - cf_t *input_cfo_corrected; cf_t *sf_buffer[SRSLTE_MAX_PORTS]; srslte::log *log_h; srslte_sync_t sync_find; @@ -233,7 +231,7 @@ private: void write(uint32_t tti, cf_t *data, uint32_t nsamples); private: void run_thread(); - const static int INTRA_FREQ_MEAS_LEN_MS = 50; + const static int INTRA_FREQ_MEAS_LEN_MS = 20; const static int INTRA_FREQ_MEAS_PERIOD_MS = 200; const static int INTRA_FREQ_MEAS_PRIO = DEFAULT_PRIORITY + 5; diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 9d539a02d..456f14ea0 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1055,10 +1055,6 @@ float phch_recv::measure::rsrp() { return 10*log10(mean_rsrp) + 30 - rx_gain_offset; } -float phch_recv::measure::rsrp_n() { - return 10*log10(mean_rsrp_n) + 30 - rx_gain_offset; -} - float phch_recv::measure::rsrq() { return 10*log10(mean_rsrq); } @@ -1169,21 +1165,18 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx) return ERROR; } - float rsrp = srslte_chest_dl_get_rsrp(&ue_dl.chest); - float rsrp_n = srslte_chest_dl_get_rsrp_neighbour(&ue_dl.chest); + float rsrp = srslte_chest_dl_get_rsrp_neighbour(&ue_dl.chest); float rsrq = srslte_chest_dl_get_rsrq(&ue_dl.chest); float snr = srslte_chest_dl_get_snr(&ue_dl.chest); float rssi = srslte_vec_avg_power_cf(buffer[0], SRSLTE_SF_LEN_PRB(current_prb)); if (cnt == 0) { mean_rsrp = rsrp; - mean_rsrp_n = rsrp_n; mean_rsrq = rsrq; mean_snr = snr; mean_rssi = rssi; } else { mean_rsrp = SRSLTE_VEC_CMA(rsrp, mean_rsrp, cnt); - mean_rsrp_n = SRSLTE_VEC_CMA(rsrp_n, mean_rsrp_n, cnt); mean_rsrq = SRSLTE_VEC_CMA(rsrq, mean_rsrq, cnt); mean_snr = SRSLTE_VEC_CMA(snr, mean_snr, cnt); mean_rssi = SRSLTE_VEC_CMA(rssi, mean_rssi, cnt); @@ -1191,7 +1184,7 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx) cnt++; log_h->debug("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm, corr-RSRP=%.1f dBm, SNR=%.1f dB\n", - cnt, nof_subframes, sf_idx, rsrp, rsrp_n, snr); + cnt, nof_subframes, sf_idx, rsrp, snr); if (cnt >= nof_subframes) { return MEASURE_OK; @@ -1220,7 +1213,6 @@ void phch_recv::scell_recv::init(srslte::log *log_h, bool sic_pss_enabled, uint3 uint32_t max_sf_size = SRSLTE_SF_LEN(max_fft_sz); sf_buffer[0] = (cf_t*) srslte_vec_malloc(sizeof(cf_t)*max_sf_size); - input_cfo_corrected = (cf_t*) srslte_vec_malloc(sizeof(cf_t)*15*max_sf_size); measure_p.init(sf_buffer, log_h, 1, max_sf_window); @@ -1257,7 +1249,6 @@ void phch_recv::scell_recv::reset() void phch_recv::scell_recv::deinit() { srslte_sync_free(&sync_find); - free(input_cfo_corrected); free(sf_buffer[0]); } @@ -1335,40 +1326,23 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset, found_cell.nof_ports = 1; // Use port 0 only for measurement measure_p.set_cell(found_cell); - // Correct CFO - /* - srslte_cfo_correct(&sync_find.cfo_corr_frame, - input_buffer, - input_cfo_corrected, - -srslte_sync_get_cfo(&sync_find)/sync_find.fft_size); - */ - switch(measure_p.run_multiple_subframes(input_buffer, peak_idx, sf_idx, nof_sf)) { case measure::MEASURE_OK: // Consider a cell to be detectable 8.1.2.2.1.1 from 36.133. Currently only using first condition if (measure_p.rsrp() > ABSOLUTE_RSRP_THRESHOLD_DBM) { - // Check the cell id has been correctly identified by using the correlation of the RS sequences - // By experimentation, typically the cross-correlation is ~3/4 dB less - if (measure_p.rsrp_n() > measure_p.rsrp() - 6) { - cells[nof_cells].pci = found_cell.id; - cells[nof_cells].rsrp = measure_p.rsrp(); - cells[nof_cells].rsrq = measure_p.rsrq(); - cells[nof_cells].offset = measure_p.frame_st_idx(); - - Info( - "INTRA: Found neighbour cell %d: PCI=%03d, RSRP=%5.1f dBm, corr-RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f, sf=%d, max_sf=%d, n_id_2=%d, CFO=%6.1f Hz\n", - nof_cells, cell_id, measure_p.rsrp(), measure_p.rsrp_n(), measure_p.frame_st_idx(), sync_find.peak_value, - sf_idx, max_sf5, n_id_2, 15000 * srslte_sync_get_cfo(&sync_find)); - - nof_cells++; - } else { - Info( - "INTRA: Found phantom cell %d: PCI=%03d, RSRP=%5.1f dBm, corr-RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f, sf=%d, max_sf=%d, n_id_2=%d, CFO=%6.1f Hz\n", - nof_cells, cell_id, measure_p.rsrp(), measure_p.rsrp_n(), measure_p.frame_st_idx(), sync_find.peak_value, - sf_idx, max_sf5, n_id_2, 15000 * srslte_sync_get_cfo(&sync_find)); - } + cells[nof_cells].pci = found_cell.id; + cells[nof_cells].rsrp = measure_p.rsrp(); + cells[nof_cells].rsrq = measure_p.rsrq(); + cells[nof_cells].offset = measure_p.frame_st_idx(); + + Info( + "INTRA: Found neighbour cell %d: PCI=%03d, RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f, sf=%d, nof_sf=%d, n_id_2=%d, CFO=%6.1f Hz\n", + nof_cells, cell_id, measure_p.rsrp(), measure_p.frame_st_idx(), sync_find.peak_value, + sf_idx, nof_sf, n_id_2, 15000 * srslte_sync_get_cfo(&sync_find)); + + nof_cells++; /* if (sic_pss_enabled) { From be84ee854a1476c73592b18ffc51ab22e7924092 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 14 Mar 2018 11:14:44 +0000 Subject: [PATCH 262/342] Changing the way that ECM context is stored to keep uplink teids active when the context is release. --- srsepc/hdr/mme/s1ap.h | 32 +- srsepc/hdr/mme/s1ap_common.h | 6 +- srsepc/hdr/mme/s1ap_nas_transport.h | 16 +- srsepc/src/mme/mme_gtpc.cc | 13 +- srsepc/src/mme/s1ap.cc | 339 +++++++++++++++----- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 50 +-- srsepc/src/mme/s1ap_nas_transport.cc | 426 ++++++++++++-------------- 7 files changed, 516 insertions(+), 366 deletions(-) diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 311a65784..52d435fbd 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -66,7 +66,7 @@ public: int get_s1_mme(); void delete_enb_ctx(int32_t assoc_id); - void delete_ues_in_enb(uint16_t enb_id); + void release_ues_ecm_ctx_in_enb(uint16_t enb_id); bool handle_s1ap_rx_pdu(srslte::byte_buffer_t *pdu, struct sctp_sndrcvinfo *enb_sri); bool handle_initiating_message(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg, struct sctp_sndrcvinfo *enb_sri); @@ -81,16 +81,20 @@ public: enb_ctx_t* find_enb_ctx(uint16_t enb_id); void add_new_enb_ctx(const enb_ctx_t &enb_ctx, const struct sctp_sndrcvinfo* enb_sri); - ue_ctx_t* find_ue_ctx(uint32_t mme_ue_s1ap_id); void add_new_ue_ctx(const ue_ctx_t &ue_ctx); + ue_ctx_t* find_ue_ctx_from_imsi(uint64_t imsi); + ue_ctx_t* find_ue_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id); - void add_new_ue_emm_ctx(const ue_emm_ctx_t &ue_emm_ctx); - void add_new_ue_ecm_ctx(const ue_ecm_ctx_t &ue_ecm_ctx); - ue_emm_ctx_t* find_ue_emm_ctx_from_imsi(uint64_t imsi); - ue_ecm_ctx_t* find_ue_ecm_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id); - bool delete_ue_emm_ctx(uint64_t imsi); - bool delete_ue_ecm_ctx(uint32_t mme_ue_s1ap_id); - void delete_ues_ecm_ctx_in_enb(uint16_t enb_id); + //ue_ctx_t* find_ue_ctx(uint32_t mme_ue_s1ap_id); + //void add_new_ue_ctx(const ue_ctx_t &ue_ctx); + + //void add_new_ue_emm_ctx(const ue_emm_ctx_t &ue_emm_ctx); + //void add_new_ue_ecm_ctx(const ue_ecm_ctx_t &ue_ecm_ctx); + //ue_emm_ctx_t* find_ue_emm_ctx_from_imsi(uint64_t imsi); + //ue_ecm_ctx_t* find_ue_ecm_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id); + //bool delete_ue_emm_ctx(uint64_t imsi); + //bool delete_ue_ecm_ctx(uint32_t mme_ue_s1ap_id); + //void delete_ues_ecm_ctx_in_enb(uint16_t enb_id); void store_tmp_ue_emm_ctx(const ue_emm_ctx_t &ue_ecm_ctx); bool get_tmp_ue_emm_ctx(uint32_t mme_ue_s1ap_id, ue_emm_ctx_t* ue_emm_ptr); @@ -122,9 +126,13 @@ private: std::map m_sctp_to_enb_id; std::map > m_enb_id_to_ue_ids; - std::map m_imsi_to_ue_emm_ctx; - std::map m_mme_ue_s1ap_id_to_ue_ecm_ctx; - std::map m_mme_ue_s1ap_id_to_tmp_ue_emm_ctx; + + std::map m_imsi_to_ue_ctx; + std::map m_mme_ue_s1ap_id_to_ue_ctx; + + //std::map m_imsi_to_ue_emm_ctx; + //std::map m_mme_ue_s1ap_id_to_ue_ecm_ctx; + //std::map m_mme_ue_s1ap_id_to_tmp_ue_emm_ctx; uint32_t m_next_mme_ue_s1ap_id; uint32_t m_next_m_tmsi; diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index 5bb60e5a6..adb9f68e0 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -122,7 +122,7 @@ typedef struct{ LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT ue_network_cap; bool ms_network_cap_present; LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT ms_network_cap; -} eps_security_ctx_t; +} eps_sec_ctx_t; typedef struct{ enum erab_state state; @@ -135,7 +135,7 @@ typedef struct{ typedef struct{ uint64_t imsi; LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT guti; - eps_security_ctx_t security_ctxt; + eps_sec_ctx_t security_ctxt; uint8_t procedure_transaction_id; emm_state_t state; uint32_t mme_ue_s1ap_id; @@ -156,7 +156,9 @@ typedef struct{ typedef struct{ ue_emm_ctx_t emm_ctx; + eps_sec_ctx_t sec_ctx; ue_ecm_ctx_t ecm_ctx; + erab_ctx_t erabs_ctx[MAX_ERABS_PER_UE]; } ue_ctx_t; }//namespace #endif diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index b107eb010..7ce83f363 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -72,14 +72,14 @@ public: srslte::byte_buffer_t *reply_buffer, bool* reply_flag, struct sctp_sndrcvinfo *enb_sri); - bool handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag); - bool handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); - bool handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); - bool handle_esm_information_response(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag); - bool handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag); - bool handle_tracking_area_update_request(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag); + bool handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag); + bool handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); + bool handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); + 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_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); + bool handle_authentication_failure(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); bool integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_buffer_t *pdu); bool short_integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_buffer_t *pdu); @@ -94,7 +94,7 @@ public: bool pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *ue_ecm_ctx, LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *erab_ctxt, struct srslte::gtpc_pdn_address_allocation_ie *paa, srslte::byte_buffer_t *nas_buffer); bool pack_identity_request(srslte::byte_buffer_t *reply_msg, uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id); - bool pack_emm_information(ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg); + bool pack_emm_information(ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_msg); bool pack_service_reject(srslte::byte_buffer_t *reply_msg, uint8_t emm_cause, uint32_t enb_ue_s1ap_id); void log_unhandled_attach_request_ies(const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT *attach_req); diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 595166494..53277e89c 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -214,16 +214,13 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu) } //Save create session response info to E-RAB context - ue_emm_ctx_t *emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(imsi); - if(emm_ctx == NULL){ - m_mme_gtpc_log->error("Could not find UE EMM context\n"); - return; - } - ue_ecm_ctx_t *ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(emm_ctx->mme_ue_s1ap_id); - if(ecm_ctx == NULL){ - m_mme_gtpc_log->error("Could not find UE ECM context\n"); + ue_ctx_t *ue_ctx = m_s1ap->find_ue_ctx_from_imsi(imsi); + if(ue_ctx == NULL){ + m_mme_gtpc_log->error("Could not find UE context\n"); return; } + ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; + ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; //Save SGW ctrl F-TEID in GTP-C context std::map::iterator it_g = m_imsi_to_gtpc_ctx.find(imsi); diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 845675057..e59740299 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -113,18 +113,17 @@ s1ap::stop() { m_s1ap_log->info("Deleting eNB context. eNB Id: 0x%x\n", enb_it->second->enb_id); m_s1ap_log->console("Deleting eNB context. eNB Id: 0x%x\n", enb_it->second->enb_id); - delete_ues_ecm_ctx_in_enb(enb_it->second->enb_id); delete enb_it->second; m_active_enbs.erase(enb_it++); } - std::map::iterator ue_it = m_imsi_to_ue_emm_ctx.begin(); - while(ue_it!=m_imsi_to_ue_emm_ctx.end()) + std::map::iterator ue_it = m_imsi_to_ue_ctx.begin(); + while(ue_it!=m_imsi_to_ue_ctx.end()) { m_s1ap_log->info("Deleting UE EMM context. IMSI: %015lu\n", ue_it->first); m_s1ap_log->console("Deleting UE EMM context. IMSI: %015lu\n", ue_it->first); delete ue_it->second; - m_imsi_to_ue_emm_ctx.erase(ue_it++); + m_imsi_to_ue_ctx.erase(ue_it++); } //Cleanup message handlers s1ap_mngmt_proc::cleanup(); @@ -336,7 +335,7 @@ s1ap::delete_enb_ctx(int32_t assoc_id) m_s1ap_log->console("Deleting eNB context. eNB Id: 0x%x\n", enb_id); //Delete connected UEs ctx - delete_ues_ecm_ctx_in_enb(enb_id); + release_ues_ecm_ctx_in_enb(enb_id); //Delete eNB delete it_ctx->second; @@ -348,20 +347,89 @@ s1ap::delete_enb_ctx(int32_t assoc_id) //UE Context Management void -s1ap::add_new_ue_emm_ctx(const ue_emm_ctx_t &ue_emm_ctx) +s1ap::add_new_ue_ctx(const ue_ctx_t &ue_ctx) { - std::map::iterator emm_ctx_it = m_imsi_to_ue_emm_ctx.find(ue_emm_ctx.imsi); - if(emm_ctx_it != m_imsi_to_ue_emm_ctx.end()) + std::map::iterator ctx_it = m_imsi_to_ue_ctx.find(ue_ctx.emm_ctx.imsi); + if(ctx_it != m_imsi_to_ue_ctx.end()) { - m_s1ap_log->warning("EMM Context already exists. Replacing EMM Context\n"); - delete emm_ctx_it->second; - m_imsi_to_ue_emm_ctx.erase(emm_ctx_it); + m_s1ap_log->warning("UE Context already exists. Replacing UE Context\n"); + delete ctx_it->second; + m_imsi_to_ue_ctx.erase(ctx_it); + } + std::map::iterator imsi_it = m_mme_ue_s1ap_id_to_imsi.find(ue_ctx.ecm_ctx.mme_ue_s1ap_id); + if(imsi_it != m_mme_ue_s1ap_id_to_imsi.end()) + { + m_s1ap_log->warning("MME UE S1AP Id already exists, replacing it.\n"); + m_mme_ue_s1ap_id_to_imsi.erase(imsi_it); } - ue_emm_ctx_t *ue_ptr = new ue_emm_ctx_t; - memcpy(ue_ptr,&ue_emm_ctx,sizeof(ue_emm_ctx)); - //This map will store UEs EMM context - m_imsi_to_ue_emm_ctx.insert(std::pair(ue_ptr->imsi,ue_ptr)); + ue_ctx_t *new_ctx = new ue_ctx_t; + memcpy(new_ctx, &ue_ctx,sizeof(ue_ctx)); + + //This map will store UEs context + m_imsi_to_ue_ctx.insert(std::pair(new_ctx->emm_ctx.imsi,new_ctx)); + m_mme_ue_s1ap_id_to_imsi.insert(std::pair(ue_ctx.ecm_ctx.mme_ue_s1ap_id,ue_ctx.emm_ctx.imsi)); + + //Store which enb currently holds the UE + std::map::iterator it_enb = m_sctp_to_enb_id.find(new_ctx->ecm_ctx.enb_sri.sinfo_assoc_id); + uint16_t enb_id = it_enb->second; + std::map >::iterator it_ue_id = m_enb_id_to_ue_ids.find(enb_id); + if(it_ue_id==m_enb_id_to_ue_ids.end()) + { + m_s1ap_log->error("Could not find eNB's UEs\n"); + return; + } + it_ue_id->second.insert(new_ctx->ecm_ctx.mme_ue_s1ap_id); + return; +} + +bool +s1ap::add_ue_ctx_to_imsi_map(const ue_ctx_t *ue_ctx) +{ + std::map::iterator ctx_it = m_imsi_to_ue_ctx.find(ue_ctx->emm_ctx.imsi); + if(ctx_it != m_imsi_to_ue_ctx.end()) + { + m_s1ap_log->error("UE Context already exists. IMSI %015lu",ue_ctx->emm_ctx.imsi); + return false; + } + if(ue_ctx->ecm_ctx.mme_ue_s1ap_id != 0) + { + std::map::iterator ctx_it2 = m_mme_ue_s1ap_id_to_ue_ctx.find(ue_ctx.ecm_ctx.mme_ue_s1ap_id); + if(ctx_it2 != m_mme_ue_s1ap_id_to_imsi.end() && ctx_it2->second != ue_ctx) + { + m_s1ap_log->error("Context identified with IMSI does not match context identified by MME UE S1AP Id.\n"); + return false; + } + } + return true; +} + +bool +s1ap::add_ue_ctx_to_mme_ue_s1ap_id_map(const ue_ctx_t *ue_ctx) +{ + if(ue_ctx->ecm_ctx.mme_ue_s1ap_id == 0) + { + m_s1ap_log->error("Could not add UE context to MME UE S1AP map. MME UE S1AP ID 0 is not valid.") + return false; + } + std::map::iterator ctx_it = m_mme_ue_s1ap_id_to_ue_ctx.find(ue_ctx->ecm_ctx.mme_ue_s1ap_id); + if(ctx_it != m_mme_ue_s1ap_id_to_ue_ctx.end()) + { + m_s1ap_log->error("UE Context already exists. MME UE S1AP Id %015lu",ue_ctx->emm_ctx.imsi); + return false; + } + if(ue_ctx->ecm_ctx.imsi != 0) + { + std::map::iterator ctx_it2 = m_mme_ue_s1ap_id_to_ue_ctx.find(ue_ctx.ecm_ctx.mme_ue_s1ap_id); + if(ctx_it2 != m_mme_ue_s1ap_id_to_imsi.end() && ctx_it2->second != ue_ctx) + { + m_s1ap_log->error("Context identified with MME UE S1AP Id does not match context identified by IMSI.\n"); + return false; + } + } + + + return true; } void @@ -389,32 +457,11 @@ s1ap::get_tmp_ue_emm_ctx(uint32_t mme_ue_s1ap_id, ue_emm_ctx_t* ue_emm_ptr) return true; } -void -s1ap::add_new_ue_ecm_ctx(const ue_ecm_ctx_t &ue_ecm_ctx) -{ - ue_ecm_ctx_t *ue_ptr = new ue_ecm_ctx_t; - memcpy(ue_ptr,&ue_ecm_ctx,sizeof(ue_ecm_ctx)); - - //This map will store UE's ECM context. - m_mme_ue_s1ap_id_to_ue_ecm_ctx.insert(std::pair(ue_ptr->mme_ue_s1ap_id,ue_ptr)); - //Store which enb currently holds the UE - std::map::iterator it_enb = m_sctp_to_enb_id.find(ue_ptr->enb_sri.sinfo_assoc_id); - uint16_t enb_id = it_enb->second; - std::map >::iterator it_ue_id = m_enb_id_to_ue_ids.find(enb_id); - if(it_ue_id==m_enb_id_to_ue_ids.end()) - { - m_s1ap_log->error("Could not find eNB's UEs\n"); - return; - } - it_ue_id->second.insert(ue_ptr->mme_ue_s1ap_id); -} - - -ue_emm_ctx_t* -s1ap::find_ue_emm_ctx_from_imsi(uint64_t imsi) +ue_ctx_t* +s1ap::find_ue_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id) { - std::map::iterator it = m_imsi_to_ue_emm_ctx.find(imsi); - if(it == m_imsi_to_ue_emm_ctx.end()) + std::map::iterator it = m_mme_ue_s1ap_id_to_ue_ctx.find(mme_ue_s1ap_id); + if(it == m_mme_ue_s1ap_id_to_imsi.end()) { return NULL; } @@ -424,11 +471,11 @@ s1ap::find_ue_emm_ctx_from_imsi(uint64_t imsi) } } -ue_ecm_ctx_t* -s1ap::find_ue_ecm_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id) +ue_ctx_t* +s1ap::find_ue_ctx_from_imsi(uint64_t imsi) { - std::map::iterator it = m_mme_ue_s1ap_id_to_ue_ecm_ctx.find(mme_ue_s1ap_id); - if(it == m_mme_ue_s1ap_id_to_ue_ecm_ctx.end()) + std::map::iterator it = m_imsi_to_ue_ctx.find(imsi); + if(it == m_imsi_to_ue_ctx.end()) { return NULL; } @@ -437,39 +484,39 @@ s1ap::find_ue_ecm_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id) return it->second; } } -bool -s1ap::delete_ue_emm_ctx(uint64_t imsi) + +void +s1ap::release_ues_ecm_ctx_in_enb(uint16_t enb_id) { - std::map::iterator ue_emm_ctx_it = m_imsi_to_ue_emm_ctx.find(imsi); - if(ue_emm_ctx_it == m_imsi_to_ue_emm_ctx.end()) + //delete UEs ctx + std::map >::iterator ues_in_enb = m_enb_id_to_ue_ids.find(enb_id); + std::set::iterator ue_id = ues_in_enb->second.begin(); + while(ue_id != ues_in_enb->second.end() ) { - m_s1ap_log->info("Cannot delete UE EMM context, UE not found. IMSI: %d\n", imsi); - return false; + std::map::iterator ue_ctx = m_mme_ue_s1ap_id_to_ue_ctx.find(*ue_id); + m_s1ap_log->info("Deleting UE context. UE-MME S1AP Id: %d\n", ue_ctx->second->mme_ue_s1ap_id); + m_s1ap_log->console("Deleting UE context. UE-MME S1AP Id: %d\n", ue_ctx->second->mme_ue_s1ap_id); + + ue_set->second.erase(mme_ue_s1ap_id); } - - //Delete UE context - m_imsi_to_ue_emm_ctx.erase(ue_emm_ctx_it); - delete ue_emm_ctx_it->second; - m_s1ap_log->info("Deleted UE EMM Context.\n"); - return true; } bool -s1ap::delete_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) +s1ap::release_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) { - std::map::iterator ue_ecm_ctx_it = m_mme_ue_s1ap_id_to_ue_ecm_ctx.find(mme_ue_s1ap_id); - if(ue_ecm_ctx_it == m_mme_ue_s1ap_id_to_ue_ecm_ctx.end()) + ue_ctx_t *ue_ctx = find_ue_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id) + if(ue_ctx == NULL) { - m_s1ap_log->info("Cannot delete UE ECM context, UE not found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); + m_s1ap_log->error("Cannot release UE ECM context, UE not found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); return false; } - ue_ecm_ctx_t* ue_ecm_ctx = ue_ecm_ctx_it->second; + ue_ecm_ctx_t* ecm_ctx = &ue_ctx->ecm_ctx; //Delete UE within eNB UE set - std::map::iterator it = m_sctp_to_enb_id.find(ue_ecm_ctx->enb_sri.sinfo_assoc_id); + std::map::iterator it = m_sctp_to_enb_id.find(ecm_ctx->enb_sri.sinfo_assoc_id); if(it == m_sctp_to_enb_id.end() ) { - m_s1ap_log->error("Could not find eNB for this request.\n"); + m_s1ap_log->error("Could not find eNB for UE release request.\n"); return false; } uint16_t enb_id = it->second; @@ -481,31 +528,42 @@ s1ap::delete_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) } ue_set->second.erase(mme_ue_s1ap_id); - //Delete UE context - m_mme_ue_s1ap_id_to_ue_ecm_ctx.erase(ue_ecm_ctx_it); - delete ue_ecm_ctx; - m_s1ap_log->info("Deleted UE ECM Context.\n"); + //Release UE ECM context + m_mme_ue_s1ap_id_to_imsi.erase(mme_ue_s1ap_id); + ecm_ctx->state = ECM_STATE_IDLE; + ecm_ctx->mme_ue_s1ap_id = 0; + ecm_ctx->enb_ue_s1ap_id = 0; + m_s1ap_log->info("Released UE ECM Context.\n"); return true; } -void -s1ap::delete_ues_ecm_ctx_in_enb(uint16_t enb_id) +bool +s1ap::delete_ue_ctx(uint64_t imsi) { - //delete UEs ctx - std::map >::iterator ues_in_enb = m_enb_id_to_ue_ids.find(enb_id); - std::set::iterator ue_id = ues_in_enb->second.begin(); - while(ue_id != ues_in_enb->second.end() ) + ue_ctx_t *ue_ctx = find_ue_ctx_from_imsi(imsi); + if(ue_ctx == NULL) { - std::map::iterator ue_ctx = m_mme_ue_s1ap_id_to_ue_ecm_ctx.find(*ue_id); - m_s1ap_log->info("Deleting UE context. UE-MME S1AP Id: %d\n", ue_ctx->second->mme_ue_s1ap_id); - m_s1ap_log->console("Deleting UE context. UE-MME S1AP Id: %d\n", ue_ctx->second->mme_ue_s1ap_id); - m_mme_ue_s1ap_id_to_ue_ecm_ctx.erase(ue_ctx); //remove from general MME map - delete ue_ctx->second; //delete UE context - ues_in_enb->second.erase(ue_id++); //erase from the eNB's UE set + m_s1ap_log->info("Cannot delete UE context, UE not found. IMSI: %d\n", imsi); + return false; + } + + //Make sure to release ECM ctx + if(ue_ctx->ecm_ctx.state == ECM_STATE_CONNECTED) + { + release_ue_ecm_ctx(ue_ctx->ecm_state.mme_ue_s1ap_id); } + + //Delete UE context + m_imsi_to_ue_ctx.erase(imsi); + delete ue_ctx; + m_s1ap_log->info("Deleted UE Context.\n"); + return true; } + + + //UE Bearer Managment void s1ap::activate_eps_bearer(uint64_t imsi, uint8_t ebi) @@ -580,3 +638,126 @@ s1ap::print_enb_ctx_info(const std::string &prefix, const enb_ctx_t &enb_ctx) } } //namespace srsepc + + /* +void +s1ap::add_new_ue_emm_ctx(const ue_emm_ctx_t &ue_emm_ctx) +{ + std::map::iterator emm_ctx_it = m_imsi_to_ue_emm_ctx.find(ue_emm_ctx.imsi); + if(emm_ctx_it != m_imsi_to_ue_emm_ctx.end()) + { + m_s1ap_log->warning("EMM Context already exists. Replacing EMM Context\n"); + delete emm_ctx_it->second; + m_imsi_to_ue_emm_ctx.erase(emm_ctx_it); + } + + ue_emm_ctx_t *ue_ptr = new ue_emm_ctx_t; + memcpy(ue_ptr,&ue_emm_ctx,sizeof(ue_emm_ctx)); + //This map will store UEs EMM context + m_imsi_to_ue_emm_ctx.insert(std::pair(ue_ptr->imsi,ue_ptr)); +} + */ + +/* + void + s1ap::add_new_ue_ecm_ctx(const ue_ecm_ctx_t &ue_ecm_ctx) + { + ue_ecm_ctx_t *ue_ptr = new ue_ecm_ctx_t; + memcpy(ue_ptr,&ue_ecm_ctx,sizeof(ue_ecm_ctx)); + + //This map will store UE's ECM context. + m_mme_ue_s1ap_id_to_ue_ecm_ctx.insert(std::pair(ue_ptr->mme_ue_s1ap_id,ue_ptr)); + //Store which enb currently holds the UE + std::map::iterator it_enb = m_sctp_to_enb_id.find(ue_ptr->enb_sri.sinfo_assoc_id); + uint16_t enb_id = it_enb->second; + std::map >::iterator it_ue_id = m_enb_id_to_ue_ids.find(enb_id); + if(it_ue_id==m_enb_id_to_ue_ids.end()) + { + m_s1ap_log->error("Could not find eNB's UEs\n"); + return; + } + it_ue_id->second.insert(ue_ptr->mme_ue_s1ap_id); + } + */ + /* +ue_emm_ctx_t* +s1ap::find_ue_emm_ctx_from_imsi(uint64_t imsi) +{ + std::map::iterator it = m_imsi_to_ue_emm_ctx.find(imsi); + if(it == m_imsi_to_ue_emm_ctx.end()) + { + return NULL; + } + else + { + return it->second; + } +} + +ue_ecm_ctx_t* +s1ap::find_ue_ecm_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id) +{ + std::map::iterator it = m_mme_ue_s1ap_id_to_ue_ecm_ctx.find(mme_ue_s1ap_id); + if(it == m_mme_ue_s1ap_id_to_ue_ecm_ctx.end()) + { + return NULL; + } + else + { + return it->second; + } +}*/ + /* +bool +s1ap::delete_ue_emm_ctx(uint64_t imsi) +{ + std::map::iterator ue_emm_ctx_it = m_imsi_to_ue_emm_ctx.find(imsi); + if(ue_emm_ctx_it == m_imsi_to_ue_emm_ctx.end()) + { + m_s1ap_log->info("Cannot delete UE EMM context, UE not found. IMSI: %d\n", imsi); + return false; + } + + //Delete UE context + m_imsi_to_ue_emm_ctx.erase(ue_emm_ctx_it); + delete ue_emm_ctx_it->second; + m_s1ap_log->info("Deleted UE EMM Context.\n"); + return true; +} + */ + /* +bool +s1ap::delete_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) +{ + std::map::iterator ue_ecm_ctx_it = m_mme_ue_s1ap_id_to_ue_ecm_ctx.find(mme_ue_s1ap_id); + if(ue_ecm_ctx_it == m_mme_ue_s1ap_id_to_ue_ecm_ctx.end()) + { + m_s1ap_log->info("Cannot delete UE ECM context, UE not found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); + return false; + } + ue_ecm_ctx_t* ue_ecm_ctx = ue_ecm_ctx_it->second; + + //Delete UE within eNB UE set + std::map::iterator it = m_sctp_to_enb_id.find(ue_ecm_ctx->enb_sri.sinfo_assoc_id); + if(it == m_sctp_to_enb_id.end() ) + { + m_s1ap_log->error("Could not find eNB for this request.\n"); + return false; + } + uint16_t enb_id = it->second; + std::map >::iterator ue_set = m_enb_id_to_ue_ids.find(enb_id); + if(ue_set == m_enb_id_to_ue_ids.end()) + { + m_s1ap_log->error("Could not find the eNB's UEs.\n"); + return false; + } + ue_set->second.erase(mme_ue_s1ap_id); + + //Delete UE context + m_mme_ue_s1ap_id_to_ue_ecm_ctx.erase(ue_ecm_ctx_it); + delete ue_ecm_ctx; + m_s1ap_log->info("Deleted UE ECM Context.\n"); + + return true; +} + */ diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 34e0c8db3..3485b6e2f 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -205,27 +205,24 @@ bool s1ap_ctx_mngmt_proc::handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *in_ctxt_resp) { uint32_t mme_ue_s1ap_id = in_ctxt_resp->MME_UE_S1AP_ID.MME_UE_S1AP_ID; - ue_ecm_ctx_t *ue_ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); - if (ue_ecm_ctx == NULL) + ue_ctx_t *ue_ctx = m_s1ap->find_ue_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); + if (ue_ctx == NULL) { - m_s1ap_log->error("Could not find UE's ECM context in active UE's map\n"); + m_s1ap_log->error("Could not find UE's context in active UE's map\n"); return false; } - ue_emm_ctx_t *emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); - if (emm_ctx == NULL) - { - m_s1ap_log->error("Could not find UE's EMM context in active UE's map\n"); - return false; - } + ue_emm_ctx_t * emm_ctx = &ue_ctx->emm_ctx; + ue_ecm_ctx_t * ecm_ctx = &ue_ctx->ecm_ctx; + m_s1ap_log->console("Received Initial Context Setup Response\n"); //Setup E-RABs for(uint32_t i=0; iE_RABSetupListCtxtSURes.len;i++) { uint8_t erab_id = in_ctxt_resp->E_RABSetupListCtxtSURes.buffer[i].e_RAB_ID.E_RAB_ID; - erab_ctx_t *erab_ctx = &ue_ecm_ctx->erabs_ctx[erab_id]; + erab_ctx_t *erab_ctx = &ecm_ctx->erabs_ctx[erab_id]; if (erab_ctx->state != ERAB_CTX_REQUESTED) { - m_s1ap_log->error("E-RAB requested was not active %d\n",erab_id); + m_s1ap_log->error("E-RAB requested was not previously requested %d\n",erab_id); return false; } //Mark E-RAB with context setup @@ -254,7 +251,7 @@ s1ap_ctx_mngmt_proc::handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_I { m_s1ap_log->console("Initial Context Setup Response triggered from Service Request.\n"); m_s1ap_log->console("Sending Modify Bearer Request.\n"); - m_mme_gtpc->send_modify_bearer_request(ue_ecm_ctx->imsi, &ue_ecm_ctx->erabs_ctx[5]); + m_mme_gtpc->send_modify_bearer_request(emm_ctx->imsi, &ecm_ctx->erabs_ctx[5]); } return true; } @@ -269,13 +266,14 @@ s1ap_ctx_mngmt_proc::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECON m_s1ap_log->info("Received UE Context Release Request. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); m_s1ap_log->console("Received UE Context Release Request. MME-UE S1AP Id %d\n", mme_ue_s1ap_id); - ue_ecm_ctx_t *ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); - if(ecm_ctx == NULL) + ue_ctx_t * ue_ctx = m_s1ap->find_ue_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); + if(ue_ctx == NULL) { - m_s1ap_log->info("No UE ECM context to release found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); - m_s1ap_log->console("No UE ECM context to release found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); + m_s1ap_log->info("No UE context to release found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); + m_s1ap_log->console("No UE context to release found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); return false; } + ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; //Delete user plane context at the SPGW (but keep GTP-C connection). if (ecm_ctx->state == ECM_STATE_CONNECTED) @@ -284,23 +282,27 @@ s1ap_ctx_mngmt_proc::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECON m_s1ap_log->console("There are active E-RABs, send release access mearers request"); m_s1ap_log->info("There are active E-RABs, send release access mearers request"); m_mme_gtpc->send_release_access_bearers_request(ecm_ctx->imsi); + //The handle_releease_access_bearers_response function will make sure to mark E-RABS DEACTIVATED + //It will release the UEs downstream S1-u and keep the upstream S1-U connection active. } else { //No ECM Context to release m_s1ap_log->info("UE is not ECM connected. No need to release S1-U. MME UE S1AP Id %d\n", mme_ue_s1ap_id); m_s1ap_log->console("UE is not ECM connected. No need to release S1-U. MME UE S1AP Id %d\n", mme_ue_s1ap_id); + //Make sure E-RABS are merked as DEACTIVATED. + for(int i=0;ierabs_ctx[i].state = ERAB_DEACTIVATED; + } } - //m_s1ap->delete_ue_ctx(ue_ctx); - for(int i=0;ierabs_ctx[i].state = ERAB_DEACTIVATED; - } + //Delete UE context - ecm_ctx->state = ECM_STATE_DISCONNECTED; + ecm_ctx->state = ECM_STATE_IDLE; + ecm_ctx->enb_ue_s1ap_id = 0; ecm_ctx->mme_ue_s1ap_id = 0; - m_s1ap_log->info("UE ECM Disconnected.\n"); - m_s1ap_log->console("Deleted UE ECM Context.\n"); + m_s1ap_log->info("UE is ECM IDLE.\n"); + m_s1ap_log->console("UE is ECM IDLE.\n"); return true; } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 2227cddda..0cde1635d 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -140,14 +140,16 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA bool mac_valid = false; //Get UE ECM context - ue_ecm_ctx_t *ue_ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); - if(ue_ecm_ctx == NULL) + ue_ctx_t *ue_ctx = m_s1ap->find_ue_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); + if(ue_ctx == NULL) { m_s1ap_log->warning("Received uplink NAS, but could not find UE ECM context. MME-UE S1AP id: %lu\n",mme_ue_s1ap_id); return false; } m_s1ap_log->debug("Received uplink NAS and found UE ECM context. MME-UE S1AP id: %lu\n",mme_ue_s1ap_id); + ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; + ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; //Parse NAS message header srslte::byte_buffer_t *nas_msg = m_pool->allocate(); @@ -161,15 +163,13 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA //Find UE EMM context if message is security protected. if(sec_hdr_type != LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS) { - //Get EMM context to do integrity check/de-chiphering - ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); - if(ue_emm_ctx == NULL) + //Make sure EMM context is set-up, to do integrity check/de-chiphering + if(emm_ctx->imsi == 0) { //No EMM context found. //Perhaps a temporary context is being created? - //This can happen with integrity protected identity reponse and authentication response messages - if( !(msg_type == LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE && sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY) && - !(msg_type == LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE && sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY)) + //This can happen with integrity protected identity reponse messages + if( !(msg_type == LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE && sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY)) { m_s1ap_log->warning("Uplink NAS: could not find security context for integrity protected message. MME-UE S1AP id: %lu\n",mme_ue_s1ap_id); m_pool->deallocate(nas_msg); @@ -191,12 +191,12 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA case LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE: m_s1ap_log->info("Uplink NAS: Received Identity Response\n"); m_s1ap_log->console("Uplink NAS: Received Identity Response\n"); - handle_identity_response(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); + handle_identity_response(nas_msg, ue_ctx, reply_buffer, reply_flag); break; case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE: m_s1ap_log->info("Uplink NAS: Received Authentication Response\n"); m_s1ap_log->console("Uplink NAS: Received Authentication Response\n"); - handle_nas_authentication_response(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); + handle_nas_authentication_response(nas_msg, ue_ctx, reply_buffer, reply_flag); break; default: m_s1ap_log->warning("Unhandled Plain NAS message 0x%x\n", msg_type ); @@ -205,14 +205,7 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA return false; } //Increment UL NAS count. - ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); - if(ue_emm_ctx == NULL) - { - m_s1ap_log->warning("Could not find UE EMM context in ", msg_type ); - m_pool->deallocate(nas_msg); - return false; - } - ue_emm_ctx->security_ctxt.ul_nas_count++; + emm_ctx->security_ctxt.ul_nas_count++; } else if(sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT || sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT) { @@ -220,11 +213,11 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA case LIBLTE_MME_MSG_TYPE_SECURITY_MODE_COMPLETE: m_s1ap_log->info("Uplink NAS: Received Security Mode Complete\n"); m_s1ap_log->console("Uplink NAS: Received Security Mode Complete\n"); - ue_emm_ctx->security_ctxt.ul_nas_count = 0; - ue_emm_ctx->security_ctxt.dl_nas_count = 0; - mac_valid = integrity_check(ue_emm_ctx,nas_msg); + emm_ctx->security_ctxt.ul_nas_count = 0; + emm_ctx->security_ctxt.dl_nas_count = 0; + mac_valid = integrity_check(emm_ctx,nas_msg); if(mac_valid){ - handle_nas_security_mode_complete(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); + handle_nas_security_mode_complete(nas_msg, ue_ctx, reply_buffer, reply_flag); } else { m_s1ap_log->warning("Invalid MAC in Security Mode Command Complete message.\n" ); } @@ -237,7 +230,7 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA else if(sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY || sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED) { //Integrity protected NAS message, possibly chiphered. - ue_emm_ctx->security_ctxt.ul_nas_count++; + emm_ctx->security_ctxt.ul_nas_count++; mac_valid = integrity_check(ue_emm_ctx,nas_msg); if(!mac_valid){ m_s1ap_log->warning("Invalid MAC in NAS message type 0x%x.\n", msg_type); @@ -248,20 +241,20 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA case LIBLTE_MME_MSG_TYPE_ATTACH_COMPLETE: m_s1ap_log->info("Uplink NAS: Received Attach Complete\n"); m_s1ap_log->console("Uplink NAS: Received Attach Complete\n"); - handle_nas_attach_complete(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); + handle_nas_attach_complete(nas_msg, ue_ctx, reply_buffer, reply_flag); break; case LIBLTE_MME_MSG_TYPE_ESM_INFORMATION_RESPONSE: m_s1ap_log->info("Uplink NAS: Received ESM Information Response\n"); m_s1ap_log->console("Uplink NAS: Received ESM Information Response\n"); - handle_esm_information_response(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); + handle_esm_information_response(nas_msg, ue_ctx, reply_buffer, reply_flag); break; case LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REQUEST: m_s1ap_log->info("UL NAS: Tracking Area Update Request\n"); - handle_tracking_area_update_request(nas_msg, ue_ecm_ctx, reply_buffer, reply_flag); + 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_ecm_ctx, reply_buffer, reply_flag); + handle_authentication_failure(nas_msg, ue_ctx, reply_buffer, reply_flag); break; default: m_s1ap_log->warning("Unhandled NAS integrity protected message 0x%x\n", msg_type ); @@ -281,8 +274,8 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA if(*reply_flag == true) { if(ue_emm_ctx != NULL){ - m_s1ap_log->console("DL NAS: Sent Downlink NAs Message. DL NAS Count=%d, UL NAS count=%d\n",ue_emm_ctx->security_ctxt.dl_nas_count,ue_emm_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_emm_ctx->security_ctxt.dl_nas_count, ue_emm_ctx->security_ctxt.ul_nas_count); + m_s1ap_log->console("DL NAS: Sent Downlink NAs Message. DL NAS Count=%d, UL NAS count=%d\n",emm_ctx->security_ctxt.dl_nas_count,emm_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",emm_ctx->security_ctxt.dl_nas_count, emm_ctx->security_ctxt.ul_nas_count); } else{ m_s1ap_log->console("DL NAS: Sent Downlink NAS Message\n"); @@ -290,7 +283,6 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA } } m_pool->deallocate(nas_msg); - return true; } @@ -353,54 +345,54 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, uint8_t rand[16]; uint8_t xres[8]; - - ue_emm_ctx_t ue_emm_ctx; - ue_ecm_ctx_t ue_ecm_ctx; + ue_ctx_t ue_ctx; + ue_emm_ctx_t *emm_ctx = &ue_ctx.emm_ctx; + ue_ecm_ctx_t *ecm_ctx = &ue_ctx.ecm_ctx; //Set UE's EMM context - ue_emm_ctx.imsi = 0; + emm_ctx->imsi = 0; for(int i=0;i<=14;i++){ - ue_emm_ctx.imsi += attach_req.eps_mobile_id.imsi[i]*std::pow(10,14-i); + emm_ctx->imsi += attach_req.eps_mobile_id.imsi[i]*std::pow(10,14-i); } - ue_emm_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); - ue_emm_ctx.state = EMM_STATE_DEREGISTERED; + emm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + emm_ctx->state = EMM_STATE_DEREGISTERED; //Save UE network capabilities - memcpy(&ue_emm_ctx.security_ctxt.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT)); - ue_emm_ctx.security_ctxt.ms_network_cap_present = attach_req.ms_network_cap_present; + memcpy(&emm_ctx->security_ctxt.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT)); + emm_ctx->security_ctxt.ms_network_cap_present = attach_req.ms_network_cap_present; if(attach_req.ms_network_cap_present) { - memcpy(&ue_emm_ctx.security_ctxt.ms_network_cap, &attach_req.ms_network_cap, sizeof(LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT)); + memcpy(&emm_ctx->security_ctxt.ms_network_cap, &attach_req.ms_network_cap, sizeof(LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT)); } uint8_t eps_bearer_id = pdn_con_req.eps_bearer_id; //TODO: Unused - ue_emm_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id; + emm_ctx->procedure_transaction_id = pdn_con_req.proc_transaction_id; //Initialize NAS count - ue_emm_ctx.security_ctxt.ul_nas_count = 0; - ue_emm_ctx.security_ctxt.dl_nas_count = 0; - + emm_ctx->security_ctxt.ul_nas_count = 0; + emm_ctx->security_ctxt.dl_nas_count = 0; //Set UE ECM context - ue_ecm_ctx.imsi = ue_emm_ctx.imsi; - ue_ecm_ctx.mme_ue_s1ap_id = ue_emm_ctx.mme_ue_s1ap_id; + ecm_ctx->imsi = emm_ctx->imsi; + ecm_ctx->mme_ue_s1ap_id = emm_ctx->mme_ue_s1ap_id; + //Set eNB information - ue_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; - memcpy(&ue_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + memcpy(&ecm_ctx->enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); //Save whether secure ESM information transfer is necessary - ue_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; + ecm_ctx->eit = pdn_con_req.esm_info_transfer_flag_present; //Initialize E-RABs for(uint i = 0 ; i< MAX_ERABS_PER_UE; i++) { - ue_ecm_ctx.erabs_ctx[i].state = ERAB_DEACTIVATED; - ue_ecm_ctx.erabs_ctx[i].erab_id = i; + ecm_ctx->erabs_ctx[i].state = ERAB_DEACTIVATED; + ecm_ctx->erabs_ctx[i].erab_id = i; } //Log Attach Request information - m_s1ap_log->console("Attach request -- IMSI: %015lu\n", ue_emm_ctx.imsi); - m_s1ap_log->info("Attach request -- IMSI: %015lu\n", ue_emm_ctx.imsi); - m_s1ap_log->console("Attach request -- eNB-UE S1AP Id: %d, MME-UE S1AP Id: %d\n", ue_ecm_ctx.enb_ue_s1ap_id, ue_ecm_ctx.mme_ue_s1ap_id); - m_s1ap_log->info("Attach request -- eNB-UE S1AP Id: %d, MME-UE S1AP Id: %d\n", ue_ecm_ctx.enb_ue_s1ap_id, ue_ecm_ctx.mme_ue_s1ap_id); + m_s1ap_log->console("Attach request -- IMSI: %015lu\n", emm_ctx->imsi); + m_s1ap_log->info("Attach request -- IMSI: %015lu\n", emm_ctx->imsi); + m_s1ap_log->console("Attach request -- eNB-UE S1AP Id: %d, MME-UE S1AP Id: %d\n", ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id); + m_s1ap_log->info("Attach request -- eNB-UE S1AP Id: %d, MME-UE S1AP Id: %d\n", ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id); m_s1ap_log->console("Attach request -- Attach type: %d\n", attach_req.eps_attach_type); m_s1ap_log->info("Attach request -- Attach type: %d\n", attach_req.eps_attach_type); @@ -428,21 +420,20 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, m_s1ap_log->console("PDN Connectivity Request -- ESM Information Transfer requested: %s\n", pdn_con_req.esm_info_transfer_flag_present ? "true" : "false"); //Save attach request type - ue_emm_ctx.attach_type = attach_req.eps_attach_type; + emm_ctx->attach_type = attach_req.eps_attach_type; //Get Authentication Vectors from HSS - if(!m_hss->gen_auth_info_answer(ue_emm_ctx.imsi, ue_emm_ctx.security_ctxt.k_asme, autn, rand, ue_emm_ctx.security_ctxt.xres)) + if(!m_hss->gen_auth_info_answer(emm_ctx->imsi, emm_ctx->security_ctxt.k_asme, autn, rand, emm_ctx->security_ctxt.xres)) { - m_s1ap_log->console("User not found. IMSI %015lu\n",ue_emm_ctx.imsi); - m_s1ap_log->info("User not found. IMSI %015lu\n",ue_emm_ctx.imsi); + m_s1ap_log->console("User not found. IMSI %015lu\n",emm_ctx->imsi); + m_s1ap_log->info("User not found. IMSI %015lu\n",emm_ctx->imsi); return false; } - m_s1ap->add_new_ue_emm_ctx(ue_emm_ctx); - m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); + m_s1ap->add_new_ue_ctx(ue_ctx); //Pack NAS Authentication Request in Downlink NAS Transport msg - pack_authentication_request(reply_buffer, ue_ecm_ctx.enb_ue_s1ap_id, ue_ecm_ctx.mme_ue_s1ap_id, autn, rand); + pack_authentication_request(reply_buffer, ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, autn, rand); //Send reply to eNB *reply_flag = true; @@ -542,7 +533,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, m_s1ap_log->console("Could not find M-TMSI=0x%x. Sending ID request\n",m_tmsi); m_s1ap_log->info("Could not find M-TMSI=0x%x. Sending Id Request\n", m_tmsi); - m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); + //m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); //We do not know the IMSI of the UE yet //This will be removed when the identity response is received @@ -558,45 +549,48 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, m_s1ap_log->console("Attach Request -- Found M-TMSI: %d\n",m_tmsi); m_s1ap_log->console("Attach Request -- IMSI: %d\n",it->second); //Get UE EMM context - ue_emm_ctx_t *ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(it->second); - if(ue_emm_ctx!=NULL) + ue_ctx_t *ue_ctx = m_s1ap->find_ue_ctx_from_imsi(it->second); + if(ue_ctx!=NULL) { - m_s1ap_log->console("Found UE context. IMSI: %015lu\n",ue_emm_ctx->imsi); + ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; + ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; + m_s1ap_log->console("Found UE context. IMSI: %015lu\n",emm_ctx->imsi); + //Check NAS integrity bool msg_valid = false; - ue_emm_ctx->security_ctxt.ul_nas_count++; - msg_valid = integrity_check(ue_emm_ctx,nas_msg); + emm_ctx->security_ctxt.ul_nas_count++; + msg_valid = integrity_check(emm_ctx,nas_msg); if(msg_valid == true) { //Create new MME UE S1AP Identity - ue_emm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + emm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); //Set EMM as de-registered - ue_emm_ctx->state = EMM_STATE_DEREGISTERED; + emm_ctx->state = EMM_STATE_DEREGISTERED; //Save Attach type - ue_emm_ctx->attach_type = attach_req.eps_attach_type; - //Create UE ECM context - ue_ecm_ctx_t ue_ecm_ctx; + emm_ctx->attach_type = attach_req.eps_attach_type; //Set UE ECM context - ue_ecm_ctx.imsi = ue_emm_ctx->imsi; - ue_ecm_ctx.mme_ue_s1ap_id = ue_emm_ctx->mme_ue_s1ap_id; + ecm_ctx->imsi = ecm_ctx->imsi; + ecm_ctx->mme_ue_s1ap_id = ecm_ctx->mme_ue_s1ap_id; + //Set eNB information - ue_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; - memcpy(&ue_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + memcpy(&ecm_ctx->enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); //Save whether secure ESM information transfer is necessary - ue_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; + ecm_ctx->eit = pdn_con_req.esm_info_transfer_flag_present; //Initialize E-RABs for(uint i = 0 ; i< MAX_ERABS_PER_UE; i++) { - ue_ecm_ctx.erabs_ctx[i].state = ERAB_DEACTIVATED; - ue_ecm_ctx.erabs_ctx[i].erab_id = i; + ecm_ctx->erabs_ctx[i].state = ERAB_DEACTIVATED; + ecm_ctx->erabs_ctx[i].erab_id = i; } - m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); + + //m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); //Create session request m_s1ap_log->console("GUTI Attach -- NAS Integrity OK."); - m_mme_gtpc->send_create_session_request(ue_emm_ctx->imsi); + m_mme_gtpc->send_create_session_request(emm_ctx->imsi); *reply_flag = false; //No reply needed return true; } @@ -649,8 +643,8 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, return true; } - ue_emm_ctx_t *emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(it->second); - if(emm_ctx == NULL || emm_ctx->state != EMM_STATE_REGISTERED) + ue_ctx_t *ue_ctx = m_s1ap->find_ue_ctx_from_imsi(it->second); + if(ue_ctx == NULL || ue_ctx->emm_ctx.state != EMM_STATE_REGISTERED) { m_s1ap_log->console("UE is not EMM-Registered.\n"); m_s1ap_log->error("UE is not EMM-Registered.\n"); @@ -658,80 +652,68 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, *reply_flag = true; return true; } + ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; + ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; + emm_ctx->security_ctxt.ul_nas_count++; mac_valid = short_integrity_check(emm_ctx,nas_msg); if(mac_valid) { m_s1ap_log->console("Service Request -- Short MAC valid\n"); m_s1ap_log->info("Service Request -- Short MAC valid\n"); - ue_ecm_ctx_t *ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(emm_ctx->mme_ue_s1ap_id); - if(ecm_ctx == NULL) + if(ecm_ctx->state == ECM_STATE_CONNECTED) { - m_s1ap_log->console("UE ECM context is not initialized.\n"); - m_s1ap_log->error("UE ECM context is not initialized.\n"); - pack_service_reject(reply_buffer, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED, enb_ue_s1ap_id); - *reply_flag = true; - return true; + m_s1ap_log->error("Service Request -- User is ECM CONNECTED\n"); + + //Service request to Connected UE. + //Set eNB UE S1ap identity + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + m_s1ap_log->console("Service Request -- eNB UE S1AP Id %d \n", enb_ue_s1ap_id); + m_s1ap_log->info("Service Request -- eNB UE S1AP Id %d\n ", enb_ue_s1ap_id); + + //Delete eNB context and connect. + m_s1ap_log->console("Service Request -- User has ECM context already\n"); + m_s1ap_log->info("Service Request -- User has ECM context already\n"); + m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); + //int default_bearer_id = 5; + //m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[default_bearer_id]); + //FIXME Send Modify context request OR send ctx release command and wait for the reply. } - else + else if(ecm_ctx->state == ECM_STATE_IDLE) { - if(ecm_ctx->state == ECM_STATE_CONNECTED) + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + + //UE not connect. Connect normally. + m_s1ap_log->console("Service Request -- User is ECM DISCONNECTED\n"); + m_s1ap_log->info("Service Request -- User is ECM DISCONNECTED\n"); + //Create ECM context + ecm_ctx->imsi = emm_ctx->imsi; + ecm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + emm_ctx->mme_ue_s1ap_id = ecm_ctx->mme_ue_s1ap_id; + //Set eNB information + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + memcpy(&ecm_ctx->enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + + //Save whether secure ESM information transfer is necessary + ecm_ctx->eit = false; + + //Initialize E-RABs + for(uint i = 0 ; i< MAX_ERABS_PER_UE; i++) { - m_s1ap_log->error("Service Request -- User is ECM CONNECTED\n"); - - //Service request to Connected UE. - //Set eNB UE S1ap identity - ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; - m_s1ap_log->console("Service Request -- eNB UE S1AP Id %d \n", enb_ue_s1ap_id); - m_s1ap_log->info("Service Request -- eNB UE S1AP Id %d\n ", enb_ue_s1ap_id); - - //Delete eNB context and connect. - m_s1ap_log->console("Service Request -- User has ECM context already\n"); - m_s1ap_log->info("Service Request -- User has ECM context already\n"); - m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); - //int default_bearer_id = 5; - //m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[default_bearer_id]); - //FIXME Send Modify context request OR send ctx release command and wait for the reply. - + ecm_ctx->erabs_ctx[i].state = ERAB_DEACTIVATED; + ecm_ctx->erabs_ctx[i].erab_id = i; } - else if(ecm_ctx->state == ECM_STATE_DISCONNECTED) - { - ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; - - //UE not connect. Connect normally. - m_s1ap_log->console("Service Request -- User is ECM DISCONNECTED\n"); - m_s1ap_log->info("Service Request -- User is ECM DISCONNECTED\n"); - //Create ECM context - ecm_ctx->imsi = emm_ctx->imsi; - ecm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); - emm_ctx->mme_ue_s1ap_id = ecm_ctx->mme_ue_s1ap_id; - //Set eNB information - ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; - memcpy(&ecm_ctx->enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); - - //Save whether secure ESM information transfer is necessary - ecm_ctx->eit = false; - //Initialize E-RABs - for(uint i = 0 ; i< MAX_ERABS_PER_UE; i++) - { - ue_ecm_ctx.erabs_ctx[i].state = ERAB_DEACTIVATED; - ue_ecm_ctx.erabs_ctx[i].erab_id = i; - } - ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(emm_ctx->mme_ue_s1ap_id); - - //Re-generate K_eNB - liblte_security_generate_k_enb(emm_ctx->security_ctxt.k_asme, emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.k_enb); - m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",emm_ctx->security_ctxt.ul_nas_count); - m_s1ap_log->console("UE Ctr TEID %d\n", emm_ctx->sgw_ctrl_fteid.teid); - m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx,&ecm_ctx->erabs_ctx[5]); - - } - else - { - m_s1ap_log->console("ECM context is un-initialized.\n"); - m_s1ap_log->error("ECM context is un-initialized.\n"); - } + //Re-generate K_eNB + liblte_security_generate_k_enb(emm_ctx->security_ctxt.k_asme, emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.k_enb); + m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",emm_ctx->security_ctxt.ul_nas_count); + m_s1ap_log->console("UE Ctr TEID %d\n", emm_ctx->sgw_ctrl_fteid.teid); + m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx,&ecm_ctx->erabs_ctx[5]); + } + else + { + m_s1ap_log->console("ECM context is un-initialized.\n"); + m_s1ap_log->error("ECM context is un-initialized.\n"); } } else @@ -743,19 +725,15 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, return true; } bool -s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag) +s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag) { LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_resp; bool ue_valid=true; - ue_emm_ctx_t *ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); - if(ue_emm_ctx == NULL) - { - m_s1ap_log->error("Authentication Response -- Could not find UE EMM context.\n"); - return false; - } - m_s1ap_log->console("Authentication Response -- IMSI %015lu\n", ue_emm_ctx->imsi); + ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; + ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; + m_s1ap_log->console("Authentication Response -- IMSI %015lu\n", emm_ctx->imsi); //Get NAS authentication response LIBLTE_ERROR_ENUM err = liblte_mme_unpack_authentication_response_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &auth_resp); @@ -772,26 +750,19 @@ s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *na for(int i=0; i<8;i++) { - if(auth_resp.res[i] != ue_emm_ctx->security_ctxt.xres[i]) + if(auth_resp.res[i] != emm_ctx->security_ctxt.xres[i]) { ue_valid = false; } } if(!ue_valid) { - std::cout<security_ctxt.xres[i]; - } - std::cout<info_hex(emm_ctx->security_ctxt.xres,8, "XRES"); m_s1ap_log->console("UE Authentication Rejected.\n"); m_s1ap_log->warning("UE Authentication Rejected.\n"); //Send back Athentication Reject - pack_authentication_reject(reply_buffer, ue_ecm_ctx->enb_ue_s1ap_id, ue_ecm_ctx->mme_ue_s1ap_id); + pack_authentication_reject(reply_buffer, ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id); *reply_flag = true; m_s1ap_log->console("Downlink NAS: Sending Authentication Reject.\n"); return false; @@ -801,7 +772,7 @@ s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *na m_s1ap_log->console("UE Authentication Accepted.\n"); m_s1ap_log->info("UE Authentication Accepted.\n"); //Send Security Mode Command - pack_security_mode_command(reply_buffer, ue_emm_ctx, ue_ecm_ctx); + pack_security_mode_command(reply_buffer, emm_ctx, ecm_ctx); *reply_flag = true; m_s1ap_log->console("Downlink NAS: Sending NAS Security Mode Command.\n"); } @@ -809,15 +780,11 @@ s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *na } bool -s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag) +s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag) { - ue_emm_ctx_t *ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); - if(ue_emm_ctx == NULL) - { - m_s1ap_log->error("Could not find UE's EMM context\n"); - return false; - } + ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; + ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sm_comp; @@ -834,11 +801,11 @@ s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas m_s1ap_log->warning("IMEI-SV present but not handled"); } - m_s1ap_log->info("Security Mode Command Complete -- IMSI: %lu\n", ue_ecm_ctx->imsi); - m_s1ap_log->console("Security Mode Command Complete -- IMSI: %lu\n", ue_ecm_ctx->imsi); - if(ue_ecm_ctx->eit == true) + m_s1ap_log->info("Security Mode Command Complete -- IMSI: %lu\n", emm_ctx->imsi); + m_s1ap_log->console("Security Mode Command Complete -- IMSI: %lu\n", emm_ctx->imsi); + if(ecm_ctx->eit == true) { - pack_esm_information_request(reply_buffer, ue_emm_ctx, ue_ecm_ctx); + pack_esm_information_request(reply_buffer, emm_ctx, ecm_ctx); m_s1ap_log->console("Sending ESM information request\n"); m_s1ap_log->info("Sending ESM information request\n"); *reply_flag = true; @@ -847,14 +814,14 @@ s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas { //FIXME The packging of GTP-C messages is not ready. //This means that GTP-U tunnels are created with function calls, as opposed to GTP-C. - m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi); + m_mme_gtpc->send_create_session_request(emm_ctx->imsi); *reply_flag = false; //No reply needed } return true; } bool -s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t *ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) +s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) { LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_comp; @@ -877,11 +844,8 @@ s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, u return false; } - ue_emm_ctx_t *emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ecm_ctx->imsi); - if(emm_ctx == NULL) - { - m_s1ap_log->error("Received Attach complete, but could not find UE's EMM Context.\n"); - } + ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; + ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; m_s1ap_log->console("Unpacked Attached Complete Message. IMSI %d\n", emm_ctx->imsi); m_s1ap_log->console("Unpacked Activate Default EPS Bearer message. EPS Bearer id %d\n",act_bearer.eps_bearer_id); @@ -894,10 +858,10 @@ s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, u if(emm_ctx->state == EMM_STATE_DEREGISTERED) { //Attach requested from attach request - m_mme_gtpc->send_modify_bearer_request(ecm_ctx->imsi, &ecm_ctx->erabs_ctx[act_bearer.eps_bearer_id]); + m_mme_gtpc->send_modify_bearer_request(emm_ctx->imsi, &ecm_ctx->erabs_ctx[act_bearer.eps_bearer_id]); //Send reply to eNB m_s1ap_log->console("Packing EMM infromationi\n"); - *reply_flag = pack_emm_information(ecm_ctx, reply_msg); + *reply_flag = pack_emm_information(ue_ctx, reply_msg); m_s1ap_log->console("Sending EMM infromation, bytes %d\n",reply_msg->N_bytes); m_s1ap_log->info("Sending EMM infromation\n"); } @@ -906,7 +870,7 @@ s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, u } bool -s1ap_nas_transport::handle_esm_information_response(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) +s1ap_nas_transport::handle_esm_information_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) { LIBLTE_MME_ESM_INFORMATION_RESPONSE_MSG_STRUCT esm_info_resp; @@ -930,12 +894,12 @@ s1ap_nas_transport::handle_esm_information_response(srslte::byte_buffer_t *nas_m //FIXME The packging of GTP-C messages is not ready. //This means that GTP-U tunnels are created with function calls, as opposed to GTP-C. - m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi); + m_mme_gtpc->send_create_session_request(ue_ctx->emm_ctx.imsi); return true; } bool -s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) +s1ap_nas_transport::handle_identity_response(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]; @@ -953,40 +917,42 @@ s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ imsi += id_resp.mobile_id.imsi[i]*std::pow(10,14-i); } + ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; + ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; //Check if EMM context already exists - ue_emm_ctx_t *ue_tmp_ptr = m_s1ap->find_ue_emm_ctx_from_imsi(imsi); - if(ue_tmp_ptr != NULL) - { - m_s1ap_log->warning("Unkonw GUTI, but UE's EMM context present.\n"); - m_s1ap->delete_ue_emm_ctx(imsi); - } + //ue_ctx_t *ue_tmp_ptr = m_s1ap->find_ue_ctx_from_imsi(imsi); + //if(ue_tmp_ptr != NULL) + //{ + // m_s1ap_log->warning("Unkonw GUTI, but UE's EMM context present.\n"); + // m_s1ap->delete_ue_emm_ctx(imsi); + //} m_s1ap_log->info("Id Response -- IMSI: %015lu\n", imsi); m_s1ap_log->console("Id Response -- IMSI: %015lu\n", imsi); - ue_ecm_ctx->imsi = imsi; + ecm_ctx->imsi = imsi; //Get UE EMM context - ue_emm_ctx_t ue_emm_ctx; - if(m_s1ap->get_tmp_ue_emm_ctx(ue_ecm_ctx->mme_ue_s1ap_id, &ue_emm_ctx) == false) - { - m_s1ap_log->error("Could not find UE's temporary EMM context. MME UE S1AP Id: %d\n",ue_ecm_ctx->mme_ue_s1ap_id); - return false; - } - ue_emm_ctx.imsi=imsi; + //if(m_s1ap->get_tmp_ue_emm_ctx(ue_ecm_ctx->mme_ue_s1ap_id, &ue_emm_ctx) == false) + //{ + // m_s1ap_log->error("Could not find UE's temporary EMM context. MME UE S1AP Id: %d\n",ue_ecm_ctx->mme_ue_s1ap_id); + // return false; + //} + emm_ctx->imsi=imsi; //Get Authentication Vectors from HSS - if(!m_hss->gen_auth_info_answer(imsi, ue_emm_ctx.security_ctxt.k_asme, autn, rand, ue_emm_ctx.security_ctxt.xres)) + if(!m_hss->gen_auth_info_answer(imsi, emm_ctx->security_ctxt.k_asme, autn, rand, emm_ctx->security_ctxt.xres)) { m_s1ap_log->console("User not found. IMSI %015lu\n",imsi); m_s1ap_log->info("User not found. IMSI %015lu\n",imsi); return false; } + //Store UE EMM context - m_s1ap->add_new_ue_emm_ctx(ue_emm_ctx); + //m_s1ap->add_new_ue_emm_ctx(ue_emm_ctx); //Pack NAS Authentication Request in Downlink NAS Transport msg - pack_authentication_request(reply_msg, ue_ecm_ctx->enb_ue_s1ap_id, ue_ecm_ctx->mme_ue_s1ap_id, autn, rand); + pack_authentication_request(reply_msg, ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, autn, rand); //Send reply to eNB *reply_flag = true; @@ -999,7 +965,7 @@ s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ bool -s1ap_nas_transport::handle_tracking_area_update_request(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) +s1ap_nas_transport::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) { m_s1ap_log->console("Warning: Tracking Area Update Request messages not handled yet.\n"); @@ -1018,8 +984,8 @@ s1ap_nas_transport::handle_tracking_area_update_request(srslte::byte_buffer_t *n //Setup Dw NAS structure LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT *dw_nas = &init->choice.DownlinkNASTransport; dw_nas->ext=false; - dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ecm_ctx->mme_ue_s1ap_id; - dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ecm_ctx->enb_ue_s1ap_id; + dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ctx->ecm_ctx.mme_ue_s1ap_id; + dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ctx->ecm_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); @@ -1197,7 +1163,7 @@ s1ap_nas_transport::integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_buffer_t bool -s1ap_nas_transport::handle_authentication_failure(srslte::byte_buffer_t *nas_msg, ue_ecm_ctx_t* ue_ecm_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) +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]; @@ -1210,12 +1176,8 @@ s1ap_nas_transport::handle_authentication_failure(srslte::byte_buffer_t *nas_msg return false; } - ue_emm_ctx_t *emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); - if(emm_ctx == NULL) - { - m_s1ap_log->error("Could not find UE EMM context\n"); - return false; - } + ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; + ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; switch(auth_fail.emm_cause){ case 20: @@ -1233,22 +1195,22 @@ s1ap_nas_transport::handle_authentication_failure(srslte::byte_buffer_t *nas_msg m_s1ap_log->error("Missing fail parameter\n"); return false; } - if(!m_hss->resync_sqn(ue_ecm_ctx->imsi, auth_fail.auth_fail_param)) + if(!m_hss->resync_sqn(emm_ctx->imsi, auth_fail.auth_fail_param)) { - m_s1ap_log->console("Resynchronization failed. IMSI %015lu\n", ue_ecm_ctx->imsi); - m_s1ap_log->info("Resynchronization failed. IMSI %015lu\n", ue_ecm_ctx->imsi); + m_s1ap_log->console("Resynchronization failed. IMSI %015lu\n", emm_ctx->imsi); + m_s1ap_log->info("Resynchronization failed. IMSI %015lu\n", emm_ctx->imsi); return false; } //Get Authentication Vectors from HSS - if(!m_hss->gen_auth_info_answer(ue_ecm_ctx->imsi, emm_ctx->security_ctxt.k_asme, autn, rand, emm_ctx->security_ctxt.xres)) + if(!m_hss->gen_auth_info_answer(emm_ctx->imsi, emm_ctx->security_ctxt.k_asme, autn, rand, emm_ctx->security_ctxt.xres)) { - m_s1ap_log->console("User not found. IMSI %015lu\n", ue_ecm_ctx->imsi); - m_s1ap_log->info("User not found. IMSI %015lu\n", ue_ecm_ctx->imsi); + m_s1ap_log->console("User not found. IMSI %015lu\n", emm_ctx->imsi); + m_s1ap_log->info("User not found. IMSI %015lu\n", emm_ctx->imsi); return false; } //Pack NAS Authentication Request in Downlink NAS Transport msg - pack_authentication_request(reply_msg, ue_ecm_ctx->enb_ue_s1ap_id, ue_ecm_ctx->mme_ue_s1ap_id, autn, rand); + pack_authentication_request(reply_msg, ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, autn, rand); //Send reply to eNB *reply_flag = true; @@ -1764,10 +1726,12 @@ s1ap_nas_transport::pack_identity_request(srslte::byte_buffer_t *reply_msg, uint } bool -s1ap_nas_transport::pack_emm_information( ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte_buffer_t *reply_msg) +s1ap_nas_transport::pack_emm_information( ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_msg) { srslte::byte_buffer_t *nas_buffer = m_pool->allocate(); + ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; + ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; //Setup initiating message LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu; bzero(&tx_pdu, sizeof(LIBLTE_S1AP_S1AP_PDU_STRUCT)); @@ -1782,8 +1746,8 @@ s1ap_nas_transport::pack_emm_information( ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte //Setup Dw NAS structure LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT *dw_nas = &init->choice.DownlinkNASTransport; dw_nas->ext=false; - dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ecm_ctx->mme_ue_s1ap_id;//FIXME Change name - dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ecm_ctx->enb_ue_s1ap_id; + dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ecm_ctx->mme_ue_s1ap_id;//FIXME Change name + dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ecm_ctx->enb_ue_s1ap_id; dw_nas->HandoverRestrictionList_present=false; dw_nas->SubscriberProfileIDforRFP_present=false; @@ -1799,13 +1763,9 @@ s1ap_nas_transport::pack_emm_information( ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte emm_info.utc_and_local_time_zone_present = false; emm_info.net_dst_present = false; - ue_emm_ctx_t *ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); - if(ue_emm_ctx ==NULL) - return false; - uint8_t sec_hdr_type =2; - ue_emm_ctx->security_ctxt.dl_nas_count++; - LIBLTE_ERROR_ENUM err = liblte_mme_pack_emm_information_msg(&emm_info, sec_hdr_type, ue_emm_ctx->security_ctxt.dl_nas_count, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); + emm_ctx->security_ctxt.dl_nas_count++; + LIBLTE_ERROR_ENUM err = liblte_mme_pack_emm_information_msg(&emm_info, sec_hdr_type, emm_ctx->security_ctxt.dl_nas_count, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); if(err != LIBLTE_SUCCESS) { m_s1ap_log->error("Error packing EMM Information\n"); @@ -1814,8 +1774,8 @@ s1ap_nas_transport::pack_emm_information( ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte } uint8_t mac[4]; - srslte::security_128_eia1 (&ue_emm_ctx->security_ctxt.k_nas_int[16], - ue_emm_ctx->security_ctxt.dl_nas_count, + srslte::security_128_eia1 (&emm_ctx->security_ctxt.k_nas_int[16], + emm_ctx->security_ctxt.dl_nas_count, 0, SECURITY_DIRECTION_DOWNLINK, &nas_buffer->msg[5], From 7d37c6b9c32887245ad9d56f986ab7615f130ba4 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 14 Mar 2018 13:36:20 +0000 Subject: [PATCH 263/342] Continuing to fix compilation issues. Starting to change S1AP to use the new functions to store ctx. --- srsepc/hdr/mme/s1ap.h | 8 +++++- srsepc/src/mme/s1ap.cc | 62 ++++++++++++++++++++++-------------------- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 52d435fbd..a19402632 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -66,7 +66,6 @@ public: int get_s1_mme(); void delete_enb_ctx(int32_t assoc_id); - void release_ues_ecm_ctx_in_enb(uint16_t enb_id); bool handle_s1ap_rx_pdu(srslte::byte_buffer_t *pdu, struct sctp_sndrcvinfo *enb_sri); bool handle_initiating_message(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg, struct sctp_sndrcvinfo *enb_sri); @@ -82,9 +81,16 @@ public: void add_new_enb_ctx(const enb_ctx_t &enb_ctx, const struct sctp_sndrcvinfo* enb_sri); void add_new_ue_ctx(const ue_ctx_t &ue_ctx); + bool add_ue_ctx_to_imsi_map(const ue_ctx_t *ue_ctx); + bool add_ue_ctx_to_mme_ue_s1ap_id_map(const ue_ctx_t *ue_ctx); + ue_ctx_t* find_ue_ctx_from_imsi(uint64_t imsi); ue_ctx_t* find_ue_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id); + bool release_ue_ecm_ctx(uint32_t mme_ue_s1ap_id); + void release_ues_ecm_ctx_in_enb(uint16_t enb_id); + bool delete_ue_ctx(uint64_t imsi); + //ue_ctx_t* find_ue_ctx(uint32_t mme_ue_s1ap_id); //void add_new_ue_ctx(const ue_ctx_t &ue_ctx); diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index e59740299..a541f00e3 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -346,7 +346,7 @@ s1ap::delete_enb_ctx(int32_t assoc_id) //UE Context Management -void +/*void s1ap::add_new_ue_ctx(const ue_ctx_t &ue_ctx) { std::map::iterator ctx_it = m_imsi_to_ue_ctx.find(ue_ctx.emm_ctx.imsi); @@ -382,7 +382,7 @@ s1ap::add_new_ue_ctx(const ue_ctx_t &ue_ctx) it_ue_id->second.insert(new_ctx->ecm_ctx.mme_ue_s1ap_id); return; } - +*/ bool s1ap::add_ue_ctx_to_imsi_map(const ue_ctx_t *ue_ctx) { @@ -394,8 +394,8 @@ s1ap::add_ue_ctx_to_imsi_map(const ue_ctx_t *ue_ctx) } if(ue_ctx->ecm_ctx.mme_ue_s1ap_id != 0) { - std::map::iterator ctx_it2 = m_mme_ue_s1ap_id_to_ue_ctx.find(ue_ctx.ecm_ctx.mme_ue_s1ap_id); - if(ctx_it2 != m_mme_ue_s1ap_id_to_imsi.end() && ctx_it2->second != ue_ctx) + std::map::iterator ctx_it2 = m_mme_ue_s1ap_id_to_ue_ctx.find(ue_ctx->ecm_ctx.mme_ue_s1ap_id); + if(ctx_it2 != m_mme_ue_s1ap_id_to_ue_ctx.end() && ctx_it2->second != ue_ctx) { m_s1ap_log->error("Context identified with IMSI does not match context identified by MME UE S1AP Id.\n"); return false; @@ -409,7 +409,7 @@ s1ap::add_ue_ctx_to_mme_ue_s1ap_id_map(const ue_ctx_t *ue_ctx) { if(ue_ctx->ecm_ctx.mme_ue_s1ap_id == 0) { - m_s1ap_log->error("Could not add UE context to MME UE S1AP map. MME UE S1AP ID 0 is not valid.") + m_s1ap_log->error("Could not add UE context to MME UE S1AP map. MME UE S1AP ID 0 is not valid."); return false; } std::map::iterator ctx_it = m_mme_ue_s1ap_id_to_ue_ctx.find(ue_ctx->ecm_ctx.mme_ue_s1ap_id); @@ -420,18 +420,17 @@ s1ap::add_ue_ctx_to_mme_ue_s1ap_id_map(const ue_ctx_t *ue_ctx) } if(ue_ctx->ecm_ctx.imsi != 0) { - std::map::iterator ctx_it2 = m_mme_ue_s1ap_id_to_ue_ctx.find(ue_ctx.ecm_ctx.mme_ue_s1ap_id); - if(ctx_it2 != m_mme_ue_s1ap_id_to_imsi.end() && ctx_it2->second != ue_ctx) + std::map::iterator ctx_it2 = m_mme_ue_s1ap_id_to_ue_ctx.find(ue_ctx->ecm_ctx.mme_ue_s1ap_id); + if(ctx_it2 != m_mme_ue_s1ap_id_to_ue_ctx.end() && ctx_it2->second != ue_ctx) { m_s1ap_log->error("Context identified with MME UE S1AP Id does not match context identified by IMSI.\n"); return false; } } - - return true; } + /* void s1ap::store_tmp_ue_emm_ctx(const ue_emm_ctx_t &tmp_ue_emm_ctx) { @@ -456,12 +455,13 @@ s1ap::get_tmp_ue_emm_ctx(uint32_t mme_ue_s1ap_id, ue_emm_ctx_t* ue_emm_ptr) m_mme_ue_s1ap_id_to_tmp_ue_emm_ctx.erase(it); return true; } + */ ue_ctx_t* s1ap::find_ue_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id) { std::map::iterator it = m_mme_ue_s1ap_id_to_ue_ctx.find(mme_ue_s1ap_id); - if(it == m_mme_ue_s1ap_id_to_imsi.end()) + if(it == m_mme_ue_s1ap_id_to_ue_ctx.end()) { return NULL; } @@ -494,17 +494,20 @@ s1ap::release_ues_ecm_ctx_in_enb(uint16_t enb_id) while(ue_id != ues_in_enb->second.end() ) { std::map::iterator ue_ctx = m_mme_ue_s1ap_id_to_ue_ctx.find(*ue_id); - m_s1ap_log->info("Deleting UE context. UE-MME S1AP Id: %d\n", ue_ctx->second->mme_ue_s1ap_id); - m_s1ap_log->console("Deleting UE context. UE-MME S1AP Id: %d\n", ue_ctx->second->mme_ue_s1ap_id); - - ue_set->second.erase(mme_ue_s1ap_id); + ue_ecm_ctx_t *ecm_ctx = &ue_ctx->second->ecm_ctx; + m_s1ap_log->info("Releasing UE ECM context. UE-MME S1AP Id: %d\n", ecm_ctx->mme_ue_s1ap_id); + m_s1ap_log->console("Releasing UE ECM context. UE-MME S1AP Id: %d\n", ecm_ctx->mme_ue_s1ap_id); + ues_in_enb->second.erase(ecm_ctx->mme_ue_s1ap_id); + ecm_ctx->state = ECM_STATE_IDLE; + ecm_ctx->mme_ue_s1ap_id = 0; + ecm_ctx->enb_ue_s1ap_id = 0; } } bool s1ap::release_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) { - ue_ctx_t *ue_ctx = find_ue_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id) + ue_ctx_t *ue_ctx = find_ue_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); if(ue_ctx == NULL) { m_s1ap_log->error("Cannot release UE ECM context, UE not found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); @@ -529,7 +532,7 @@ s1ap::release_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) ue_set->second.erase(mme_ue_s1ap_id); //Release UE ECM context - m_mme_ue_s1ap_id_to_imsi.erase(mme_ue_s1ap_id); + m_mme_ue_s1ap_id_to_ue_ctx.erase(mme_ue_s1ap_id); ecm_ctx->state = ECM_STATE_IDLE; ecm_ctx->mme_ue_s1ap_id = 0; ecm_ctx->enb_ue_s1ap_id = 0; @@ -549,9 +552,9 @@ s1ap::delete_ue_ctx(uint64_t imsi) } //Make sure to release ECM ctx - if(ue_ctx->ecm_ctx.state == ECM_STATE_CONNECTED) + if(ue_ctx->ecm_ctx.mme_ue_s1ap_id != 0) { - release_ue_ecm_ctx(ue_ctx->ecm_state.mme_ue_s1ap_id); + release_ue_ecm_ctx(ue_ctx->ecm_ctx.mme_ue_s1ap_id); } //Delete UE context @@ -568,31 +571,32 @@ s1ap::delete_ue_ctx(uint64_t imsi) void s1ap::activate_eps_bearer(uint64_t imsi, uint8_t ebi) { - std::map::iterator emm_ctx_it = m_imsi_to_ue_emm_ctx.find(imsi); - if(emm_ctx_it == m_imsi_to_ue_emm_ctx.end()) + std::map::iterator ue_ctx_it = m_imsi_to_ue_ctx.find(imsi); + if(ue_ctx_it == m_imsi_to_ue_ctx.end()) { - m_s1ap_log->error("Could not find UE EMM context\n"); + m_s1ap_log->error("Could not activate EPS bearer: Could not find UE context\n"); return; } - uint32_t mme_ue_s1ap_id = emm_ctx_it->second->mme_ue_s1ap_id; - std::map::iterator ecm_ctx_it = m_mme_ue_s1ap_id_to_ue_ecm_ctx.find(mme_ue_s1ap_id); - if(ecm_ctx_it == m_mme_ue_s1ap_id_to_ue_ecm_ctx.end()) + //Make sure NAS is active + uint32_t mme_ue_s1ap_id = ue_ctx_it->second->ecm_ctx.mme_ue_s1ap_id; + std::map::iterator it = m_mme_ue_s1ap_id_to_ue_ctx.find(mme_ue_s1ap_id); + if(it == m_mme_ue_s1ap_id_to_ue_ctx.end()) { - m_s1ap_log->error("Could not find UE ECM context\n"); + m_s1ap_log->error("Could not activate EPS bearer: ECM context seems to be missing\n"); return; } - ue_ecm_ctx_t * ecm_ctx = ecm_ctx_it->second; + ue_ecm_ctx_t * ecm_ctx = &ue_ctx_it->second->ecm_ctx; if (ecm_ctx->erabs_ctx[ebi].state != ERAB_CTX_SETUP) { - m_s1ap_log->error("EPS Bearer could not be activated. MME S1AP Id %d, EPS Bearer id %d, state %d\n",mme_ue_s1ap_id,ebi,ecm_ctx->erabs_ctx[ebi].state); - m_s1ap_log->console("EPS Bearer could not be activated. MME S1AP Id %d, EPS Bearer id %d\n",mme_ue_s1ap_id,ebi,ecm_ctx->erabs_ctx[ebi].state); + m_s1ap_log->error("Could not be activate EPS Bearer, bearer in wrong state: MME S1AP Id %d, EPS Bearer id %d, state %d\n",mme_ue_s1ap_id,ebi,ecm_ctx->erabs_ctx[ebi].state); + m_s1ap_log->console("Could not be activate EPS Bearer, bearer in wrong state: MME S1AP Id %d, EPS Bearer id %d\n",mme_ue_s1ap_id,ebi,ecm_ctx->erabs_ctx[ebi].state); return; } ecm_ctx->erabs_ctx[ebi].state = ERAB_ACTIVE; ecm_ctx->state = ECM_STATE_CONNECTED; - m_s1ap_log->info("Activated EPS Bearer\n"); + m_s1ap_log->info("Activated EPS Bearer: Bearer id %d\n",ebi); return; } From 9617a63d27a638e6b15a9fa10163ea9cb6008b43 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 14 Mar 2018 15:39:43 +0000 Subject: [PATCH 264/342] continuing to change the way context is stored. Compiling now. --- srsepc/hdr/mme/s1ap.h | 5 +-- srsepc/src/mme/s1ap_nas_transport.cc | 65 ++++++++++++++++------------ 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index a19402632..b2c741d26 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -80,7 +80,6 @@ public: enb_ctx_t* find_enb_ctx(uint16_t enb_id); void add_new_enb_ctx(const enb_ctx_t &enb_ctx, const struct sctp_sndrcvinfo* enb_sri); - void add_new_ue_ctx(const ue_ctx_t &ue_ctx); bool add_ue_ctx_to_imsi_map(const ue_ctx_t *ue_ctx); bool add_ue_ctx_to_mme_ue_s1ap_id_map(const ue_ctx_t *ue_ctx); @@ -102,8 +101,8 @@ public: //bool delete_ue_ecm_ctx(uint32_t mme_ue_s1ap_id); //void delete_ues_ecm_ctx_in_enb(uint16_t enb_id); - void store_tmp_ue_emm_ctx(const ue_emm_ctx_t &ue_ecm_ctx); - bool get_tmp_ue_emm_ctx(uint32_t mme_ue_s1ap_id, ue_emm_ctx_t* ue_emm_ptr); + //void store_tmp_ue_emm_ctx(const ue_emm_ctx_t &ue_ecm_ctx); + //bool get_tmp_ue_emm_ctx(uint32_t mme_ue_s1ap_id, ue_emm_ctx_t* ue_emm_ptr); uint32_t allocate_m_tmsi(uint64_t imsi); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 0cde1635d..336d84143 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -430,7 +430,11 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, return false; } - m_s1ap->add_new_ue_ctx(ue_ctx); + //Save the UE context + ue_ctx_t *new_ctx = new ue_ctx_t; + memcpy(new_ctx,&ue_ctx,sizeof(ue_ctx_t)); + m_s1ap->add_ue_ctx_to_imsi_map(new_ctx); + m_s1ap->add_ue_ctx_to_mme_ue_s1ap_id_map(new_ctx); //Pack NAS Authentication Request in Downlink NAS Transport msg pack_authentication_request(reply_buffer, ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, autn, rand); @@ -478,48 +482,53 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, m_s1ap_log->info("Attach Request -- Could not find M-TMSI 0x%x", m_tmsi); //Could not find IMSI from M-TMSI, send Id request - ue_emm_ctx_t tmp_ue_emm_ctx; - ue_ecm_ctx_t ue_ecm_ctx; + ue_ctx_t ue_ctx; + ue_emm_ctx_t *emm_ctx = &ue_ctx.emm_ctx; + ue_ecm_ctx_t *ecm_ctx = &ue_ctx.ecm_ctx; - //Set tmp UE EMM context - tmp_ue_emm_ctx.imsi = 0; - tmp_ue_emm_ctx.state = EMM_STATE_DEREGISTERED; + //We do not know the IMSI of the UE yet + //The IMSI will be set when the identity response is received + //Set EMM ctx + emm_ctx->imsi = 0; + emm_ctx->state = EMM_STATE_DEREGISTERED; + emm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); //Save UE network capabilities - memcpy(&tmp_ue_emm_ctx.security_ctxt.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT)); - tmp_ue_emm_ctx.security_ctxt.ms_network_cap_present = attach_req.ms_network_cap_present; + memcpy(&emm_ctx->security_ctxt.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT)); + emm_ctx->security_ctxt.ms_network_cap_present = attach_req.ms_network_cap_present; if(attach_req.ms_network_cap_present) { - memcpy(&tmp_ue_emm_ctx.security_ctxt.ms_network_cap, &attach_req.ms_network_cap, sizeof(LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT)); + memcpy(&emm_ctx->security_ctxt.ms_network_cap, &attach_req.ms_network_cap, sizeof(LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT)); } //Initialize NAS count - tmp_ue_emm_ctx.security_ctxt.ul_nas_count = 0; - tmp_ue_emm_ctx.security_ctxt.dl_nas_count = 0; - tmp_ue_emm_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id; + emm_ctx->security_ctxt.ul_nas_count = 0; + emm_ctx->security_ctxt.dl_nas_count = 0; + emm_ctx->procedure_transaction_id = pdn_con_req.proc_transaction_id; //Set ECM context - ue_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; - ue_ecm_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + ecm_ctx->imsi = 0; + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + ecm_ctx->mme_ue_s1ap_id = emm_ctx->mme_ue_s1ap_id; uint8_t eps_bearer_id = pdn_con_req.eps_bearer_id; //TODO: Unused //Save attach request type - tmp_ue_emm_ctx.attach_type = attach_req.eps_attach_type; + emm_ctx->attach_type = attach_req.eps_attach_type; //Save whether ESM information transfer is necessary - ue_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; + ecm_ctx->eit = pdn_con_req.esm_info_transfer_flag_present; //m_s1ap_log->console("EPS Bearer id: %d\n", eps_bearer_id); - //Add eNB info to UE ctxt - memcpy(&ue_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + //Add eNB info to UE ctxt + memcpy(&ecm_ctx->enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); //Initialize E-RABs for(uint i = 0 ; i< MAX_ERABS_PER_UE; i++) { - ue_ecm_ctx.erabs_ctx[i].state = ERAB_DEACTIVATED; - ue_ecm_ctx.erabs_ctx[i].erab_id = i; + ecm_ctx->erabs_ctx[i].state = ERAB_DEACTIVATED; + ecm_ctx->erabs_ctx[i].erab_id = i; } - m_s1ap_log->console("Attach request -- IMSI: %015lu\n", ue_ecm_ctx.imsi); - m_s1ap_log->info("Attach request -- IMSI: %015lu\n", ue_ecm_ctx.imsi); - m_s1ap_log->console("Attach request -- eNB-UE S1AP Id: %d, MME-UE S1AP Id: %d\n", ue_ecm_ctx.enb_ue_s1ap_id, ue_ecm_ctx.mme_ue_s1ap_id); + m_s1ap_log->console("Attach request -- IMSI: %015lu\n", ecm_ctx->imsi); + m_s1ap_log->info("Attach request -- IMSI: %015lu\n", ecm_ctx->imsi); + m_s1ap_log->console("Attach request -- eNB-UE S1AP Id: %d, MME-UE S1AP Id: %d\n", ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id); m_s1ap_log->console("Attach Request -- UE Network Capabilities EEA: %d%d%d%d%d%d%d%d\n", attach_req.ue_network_cap.eea[0], attach_req.ue_network_cap.eea[1], attach_req.ue_network_cap.eea[2], attach_req.ue_network_cap.eea[3], attach_req.ue_network_cap.eea[4], attach_req.ue_network_cap.eea[5], attach_req.ue_network_cap.eea[6], attach_req.ue_network_cap.eea[7]); @@ -535,12 +544,12 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, m_s1ap_log->info("Could not find M-TMSI=0x%x. Sending Id Request\n", m_tmsi); //m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); - //We do not know the IMSI of the UE yet - //This will be removed when the identity response is received - tmp_ue_emm_ctx.mme_ue_s1ap_id = ue_ecm_ctx.mme_ue_s1ap_id; - m_s1ap->store_tmp_ue_emm_ctx(tmp_ue_emm_ctx); + //Store temporary ue context + ue_ctx_t *new_ctx = new ue_ctx_t; + memcpy(new_ctx,&ue_ctx,sizeof(ue_ctx_t)); + m_s1ap->add_ue_ctx_to_mme_ue_s1ap_id_map(new_ctx); - pack_identity_request(reply_buffer, ue_ecm_ctx.enb_ue_s1ap_id, ue_ecm_ctx.mme_ue_s1ap_id); + pack_identity_request(reply_buffer, ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id); *reply_flag = true; return true; } From f9d770e50e4e80cc35bd478cf2b70666645930ce Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 17:30:55 +0100 Subject: [PATCH 265/342] Added option for Doppler frequency correction --- lib/include/srslte/interfaces/ue_interfaces.h | 3 ++- srsue/hdr/phy/phch_recv.h | 2 ++ srsue/hdr/phy/phch_worker.h | 1 - srsue/src/main.cc | 11 ++++----- srsue/src/phy/phch_recv.cc | 23 +++++++++++++++++-- srsue/src/phy/phch_worker.cc | 16 +------------ srsue/ue.conf.example | 3 +++ 7 files changed, 34 insertions(+), 25 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 9a7a68a34..e69419983 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -474,7 +474,8 @@ typedef struct { int cqi_max; int cqi_fixed; float snr_ema_coeff; - std::string snr_estim_alg; + std::string snr_estim_alg; + bool cfo_is_doppler; bool cfo_integer_enabled; float cfo_correct_tol_hz; float cfo_pss_ema; diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index d71bcb1d5..f955b30ce 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -104,6 +104,8 @@ private: void cell_search_inc(); void cell_reselect(); + float get_cfo(); + uint32_t new_earfcn; srslte_cell_t new_cell; diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index 6f72285b2..e87603e5d 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -73,7 +73,6 @@ public: float get_rsrp(); float get_noise(); 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/main.cc b/srsue/src/main.cc index d2d029c63..00fd23cf8 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -203,6 +203,11 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { bpo::value(&args->expert.phy.equalizer_mode)->default_value("mmse"), "Equalizer mode") + ("expert.cfo_is_doppler", + bpo::value(&args->expert.phy.cfo_is_doppler)->default_value(false), + "Assume detected CFO is doppler and correct the UL in the same direction. If disabled, the CFO is assumed" + "to be caused by the local oscillator and the UL correction is in the opposite direction. Default assumes oscillator.") + ("expert.cfo_integer_enabled", bpo::value(&args->expert.phy.cfo_integer_enabled)->default_value(false), "Enables integer CFO estimation and correction.") @@ -215,12 +220,6 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { bpo::value(&args->expert.phy.cfo_pss_ema)->default_value(DEFAULT_CFO_EMA_TRACK), "CFO Exponential Moving Average coefficient for PSS estimation during TRACK.") - /* REF EMA is currently not used - ("expert.cfo_ref_ema", - bpo::value(&args->expert.phy.cfo_ref_ema)->default_value(0.01), - "CFO Exponential Moving Average coefficient for RS estimation after PSS acquisition") - */ - ("expert.cfo_ref_mask", bpo::value(&args->expert.phy.cfo_ref_mask)->default_value(1023), "Bitmask for subframes on which to run RS estimation (set to 0 to disable, default all sf)") diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 456f14ea0..38dd5b561 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -428,6 +428,25 @@ bool phch_recv::set_frequency() } } +float phch_recv::get_cfo() +{ + float cfo = srslte_ue_sync_get_cfo(&ue_sync); + + float ret = cfo*ul_dl_factor; + + if (worker_com->args->cfo_is_doppler) { + ret *= -1; + } + + if (radio_h->get_freq_offset() != 0.0f) { + /* Compensates the radio frequency offset applied equally to DL and UL */ + const float offset_hz = (float) radio_h->get_freq_offset() * (1.0f - ul_dl_factor); + ret = cfo - offset_hz; + } + + return ret/15000; +} + void phch_recv::set_sampling_rate() { current_srate = (float) srslte_sampling_freq_hz(cell.nof_prb); @@ -633,7 +652,7 @@ void phch_recv::run_thread() metrics.sfo = srslte_ue_sync_get_sfo(&ue_sync); metrics.cfo = srslte_ue_sync_get_cfo(&ue_sync); - worker->set_cfo(ul_dl_factor * metrics.cfo / 15000); + worker->set_cfo(get_cfo()); worker_com->set_sync_metrics(metrics); /* Compute TX time: Any transmission happens in TTI+4 thus advance 4 ms the reception time */ @@ -659,7 +678,7 @@ void phch_recv::run_thread() if (prach_buffer->is_ready_to_send(tti)) { srslte_timestamp_copy(&tx_time_prach, &rx_time); srslte_timestamp_add(&tx_time_prach, 0, prach::tx_advance_sf * 1e-3); - prach_buffer->send(radio_h, ul_dl_factor * metrics.cfo / 15000, worker_com->pathloss, tx_time_prach); + prach_buffer->send(radio_h, get_cfo(), worker_com->pathloss, tx_time_prach); radio_h->tx_end(); worker_com->p0_preamble = prach_buffer->get_p0_preamble(); worker_com->cur_radio_power = SRSLTE_MIN(SRSLTE_PC_MAX, worker_com->pathloss+worker_com->p0_preamble); diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index b3a33ea6c..e613719cb 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -223,20 +223,6 @@ 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) { @@ -360,7 +346,7 @@ void phch_worker::work_imp() } /* Set UL CFO before transmission */ - srslte_ue_ul_set_cfo(&ue_ul, get_ul_cfo()); + srslte_ue_ul_set_cfo(&ue_ul, cfo); /* Transmit PUSCH, PUCCH or SRS */ bool signal_ready = false; diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 52442e4af..a3de1a678 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -172,6 +172,8 @@ enable = false # cfo_correct_tol_hz: Tolerance (in Hz) for digial CFO compensation. Lower tolerance means that # a new table will be generated more often. # +# cfo_is_doppler: Assume detected CFO is doppler and correct the UL in the same direction. If disabled, the CFO is assumed +# to be caused by the local oscillator and the UL correction is in the opposite direction. Default assumes oscillator. # cfo_pss_ema: CFO Exponential Moving Average coefficient for PSS estimation during TRACK. # cfo_ref_ema: CFO Exponential Moving Average coefficient for RS estimation after PSS acquisition # cfo_ref_mask: Bitmask for subframes on which to run RS estimation (set to 0 to disable, default sf=[1, 5]) @@ -211,6 +213,7 @@ enable = false #pdsch_csi_enabled = true # Caution! Only TM1 supported! # CFO related values +#cfo_is_doppler = false #cfo_integer_enabled = false #cfo_correct_tol_hz = 1.0 #cfo_pss_ema = 0.05 From 155ac12193e85f245a601837eff9e59134dd48c7 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 17:35:11 +0100 Subject: [PATCH 266/342] Remove measObject properly when release (fixes not enough unique timers bug) --- srsue/src/upper/rrc.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 8c346bfaa..c01c2fc37 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -2462,7 +2462,10 @@ void rrc::rrc_meas::reset() filter_k_rsrp = liblte_rrc_filter_coefficient_num[LIBLTE_RRC_FILTER_COEFFICIENT_FC4]; filter_k_rsrq = liblte_rrc_filter_coefficient_num[LIBLTE_RRC_FILTER_COEFFICIENT_FC4]; objects.clear(); - active.clear(); + std::map::iterator iter = active.begin(); + while (iter != active.end()) { + remove_meas_id(iter++); + } reports_cfg.clear(); phy->meas_reset(); bzero(&pcell_measurement, sizeof(meas_value_t)); @@ -2983,12 +2986,15 @@ void rrc::rrc_meas::parse_meas_config(LIBLTE_RRC_MEAS_CONFIG_STRUCT *cfg) } else { is_new = true; active[measId->meas_id].periodic_timer = mac_timers->timer_get_unique_id(); + if (!active[measId->meas_id].periodic_timer) { + log_h->error("Could not get unique timer id\n"); + } } active[measId->meas_id].object_id = measId->meas_obj_id; active[measId->meas_id].report_id = measId->rep_cnfg_id; - log_h->info("MEAS: %s measId=%d, measObjectId=%d, reportConfigId=%d, nof_values=%d\n", + log_h->info("MEAS: %s measId=%d, measObjectId=%d, reportConfigId=%d, timer_id=%d, nof_values=%d\n", is_new?"Added":"Updated", measId->meas_id, measId->meas_obj_id, measId->rep_cnfg_id, - active[measId->meas_id].cell_values.size()); + active[measId->meas_id].periodic_timer, active[measId->meas_id].cell_values.size()); } } From 209293104f822910a428c309e47b5827c2baa642 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 18:00:26 +0100 Subject: [PATCH 267/342] Fix bug introduced in 33ebde5387ce652d39bc7506400c05ae129018cc causing the UE to disconnect when reselecting cell --- srsue/src/upper/rrc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index c01c2fc37..63d64808a 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -661,7 +661,7 @@ void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { if (!ret) { phy->cell_search_next(); } - } else if (!ho_syncing) { + } else if (state < RRC_STATE_CONNECTING) { state = RRC_STATE_CELL_SELECTING; } From 1f3ccb9bda2d44252c2cfdd1f3a05f93e186b23e Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 14 Mar 2018 18:07:07 +0000 Subject: [PATCH 268/342] Fixed bug in integrity check, UE is IMSI attaching again. --- srsepc/hdr/mme/s1ap.h | 4 ++-- srsepc/src/mme/s1ap.cc | 8 ++++++-- srsepc/src/mme/s1ap_nas_transport.cc | 13 +++---------- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index b2c741d26..d417d9442 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -80,8 +80,8 @@ public: enb_ctx_t* find_enb_ctx(uint16_t enb_id); void add_new_enb_ctx(const enb_ctx_t &enb_ctx, const struct sctp_sndrcvinfo* enb_sri); - bool add_ue_ctx_to_imsi_map(const ue_ctx_t *ue_ctx); - bool add_ue_ctx_to_mme_ue_s1ap_id_map(const ue_ctx_t *ue_ctx); + bool add_ue_ctx_to_imsi_map(ue_ctx_t *ue_ctx); + bool add_ue_ctx_to_mme_ue_s1ap_id_map(ue_ctx_t *ue_ctx); ue_ctx_t* find_ue_ctx_from_imsi(uint64_t imsi); ue_ctx_t* find_ue_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id); diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index a541f00e3..4aeb17011 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -384,7 +384,7 @@ s1ap::add_new_ue_ctx(const ue_ctx_t &ue_ctx) } */ bool -s1ap::add_ue_ctx_to_imsi_map(const ue_ctx_t *ue_ctx) +s1ap::add_ue_ctx_to_imsi_map(ue_ctx_t *ue_ctx) { std::map::iterator ctx_it = m_imsi_to_ue_ctx.find(ue_ctx->emm_ctx.imsi); if(ctx_it != m_imsi_to_ue_ctx.end()) @@ -401,11 +401,13 @@ s1ap::add_ue_ctx_to_imsi_map(const ue_ctx_t *ue_ctx) return false; } } + m_imsi_to_ue_ctx.insert(std::pair(ue_ctx->emm_ctx.imsi, ue_ctx)); + m_s1ap_log->debug("Saved UE context corresponding to IMSI %015lu\n",ue_ctx->emm_ctx.imsi); return true; } bool -s1ap::add_ue_ctx_to_mme_ue_s1ap_id_map(const ue_ctx_t *ue_ctx) +s1ap::add_ue_ctx_to_mme_ue_s1ap_id_map(ue_ctx_t *ue_ctx) { if(ue_ctx->ecm_ctx.mme_ue_s1ap_id == 0) { @@ -427,6 +429,8 @@ s1ap::add_ue_ctx_to_mme_ue_s1ap_id_map(const ue_ctx_t *ue_ctx) return false; } } + m_mme_ue_s1ap_id_to_ue_ctx.insert(std::pair(ue_ctx->ecm_ctx.mme_ue_s1ap_id, ue_ctx)); + m_s1ap_log->debug("Saved UE context corresponding to MME UE S1AP Id %d\n",ue_ctx->ecm_ctx.mme_ue_s1ap_id); return true; } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 336d84143..135e99ae2 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -136,7 +136,6 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA uint8_t pd, msg_type, sec_hdr_type; uint32_t enb_ue_s1ap_id = ul_xport->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID; uint32_t mme_ue_s1ap_id = ul_xport->MME_UE_S1AP_ID.MME_UE_S1AP_ID; - ue_emm_ctx_t *ue_emm_ctx = NULL; bool mac_valid = false; //Get UE ECM context @@ -231,7 +230,7 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA { //Integrity protected NAS message, possibly chiphered. emm_ctx->security_ctxt.ul_nas_count++; - mac_valid = integrity_check(ue_emm_ctx,nas_msg); + mac_valid = integrity_check(emm_ctx,nas_msg); if(!mac_valid){ m_s1ap_log->warning("Invalid MAC in NAS message type 0x%x.\n", msg_type); m_pool->deallocate(nas_msg); @@ -273,14 +272,8 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA if(*reply_flag == true) { - if(ue_emm_ctx != NULL){ - m_s1ap_log->console("DL NAS: Sent Downlink NAs Message. DL NAS Count=%d, UL NAS count=%d\n",emm_ctx->security_ctxt.dl_nas_count,emm_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",emm_ctx->security_ctxt.dl_nas_count, emm_ctx->security_ctxt.ul_nas_count); - } - else{ - m_s1ap_log->console("DL NAS: Sent Downlink NAS Message\n"); - m_s1ap_log->console("DL NAS: Sent Downlink NAS Message\n"); - } + m_s1ap_log->console("DL NAS: Sent Downlink NAs Message. DL NAS Count=%d, UL NAS count=%d\n",emm_ctx->security_ctxt.dl_nas_count,emm_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",emm_ctx->security_ctxt.dl_nas_count, emm_ctx->security_ctxt.ul_nas_count); } m_pool->deallocate(nas_msg); return true; From a8bfa497efa133d97379de1f404677d6ebfa7f11 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 14 Mar 2018 18:34:27 +0000 Subject: [PATCH 269/342] Remove some commented out code. --- srsepc/src/mme/s1ap.cc | 186 ----------------------------------------- 1 file changed, 186 deletions(-) diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 4aeb17011..e0f5e1422 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -346,43 +346,6 @@ s1ap::delete_enb_ctx(int32_t assoc_id) //UE Context Management -/*void -s1ap::add_new_ue_ctx(const ue_ctx_t &ue_ctx) -{ - std::map::iterator ctx_it = m_imsi_to_ue_ctx.find(ue_ctx.emm_ctx.imsi); - if(ctx_it != m_imsi_to_ue_ctx.end()) - { - m_s1ap_log->warning("UE Context already exists. Replacing UE Context\n"); - delete ctx_it->second; - m_imsi_to_ue_ctx.erase(ctx_it); - } - std::map::iterator imsi_it = m_mme_ue_s1ap_id_to_imsi.find(ue_ctx.ecm_ctx.mme_ue_s1ap_id); - if(imsi_it != m_mme_ue_s1ap_id_to_imsi.end()) - { - m_s1ap_log->warning("MME UE S1AP Id already exists, replacing it.\n"); - m_mme_ue_s1ap_id_to_imsi.erase(imsi_it); - } - - ue_ctx_t *new_ctx = new ue_ctx_t; - memcpy(new_ctx, &ue_ctx,sizeof(ue_ctx)); - - //This map will store UEs context - m_imsi_to_ue_ctx.insert(std::pair(new_ctx->emm_ctx.imsi,new_ctx)); - m_mme_ue_s1ap_id_to_imsi.insert(std::pair(ue_ctx.ecm_ctx.mme_ue_s1ap_id,ue_ctx.emm_ctx.imsi)); - - //Store which enb currently holds the UE - std::map::iterator it_enb = m_sctp_to_enb_id.find(new_ctx->ecm_ctx.enb_sri.sinfo_assoc_id); - uint16_t enb_id = it_enb->second; - std::map >::iterator it_ue_id = m_enb_id_to_ue_ids.find(enb_id); - if(it_ue_id==m_enb_id_to_ue_ids.end()) - { - m_s1ap_log->error("Could not find eNB's UEs\n"); - return; - } - it_ue_id->second.insert(new_ctx->ecm_ctx.mme_ue_s1ap_id); - return; -} -*/ bool s1ap::add_ue_ctx_to_imsi_map(ue_ctx_t *ue_ctx) { @@ -434,33 +397,6 @@ s1ap::add_ue_ctx_to_mme_ue_s1ap_id_map(ue_ctx_t *ue_ctx) return true; } - /* -void -s1ap::store_tmp_ue_emm_ctx(const ue_emm_ctx_t &tmp_ue_emm_ctx) -{ - ue_emm_ctx_t *ue_ptr = new ue_emm_ctx_t; - memcpy(ue_ptr,&tmp_ue_emm_ctx,sizeof(tmp_ue_emm_ctx)); - - //This map will store UE's ECM context. - m_mme_ue_s1ap_id_to_tmp_ue_emm_ctx.insert(std::pair(ue_ptr->mme_ue_s1ap_id,ue_ptr)); -} - -bool -s1ap::get_tmp_ue_emm_ctx(uint32_t mme_ue_s1ap_id, ue_emm_ctx_t* ue_emm_ptr) -{ - - std::map::iterator it = m_mme_ue_s1ap_id_to_tmp_ue_emm_ctx.find(mme_ue_s1ap_id); - if(it == m_mme_ue_s1ap_id_to_tmp_ue_emm_ctx.end() ) - { - return false; - } - memcpy(ue_emm_ptr, it->second,sizeof(ue_emm_ctx_t)); - delete it->second; - m_mme_ue_s1ap_id_to_tmp_ue_emm_ctx.erase(it); - return true; -} - */ - ue_ctx_t* s1ap::find_ue_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id) { @@ -647,125 +583,3 @@ s1ap::print_enb_ctx_info(const std::string &prefix, const enb_ctx_t &enb_ctx) } //namespace srsepc - /* -void -s1ap::add_new_ue_emm_ctx(const ue_emm_ctx_t &ue_emm_ctx) -{ - std::map::iterator emm_ctx_it = m_imsi_to_ue_emm_ctx.find(ue_emm_ctx.imsi); - if(emm_ctx_it != m_imsi_to_ue_emm_ctx.end()) - { - m_s1ap_log->warning("EMM Context already exists. Replacing EMM Context\n"); - delete emm_ctx_it->second; - m_imsi_to_ue_emm_ctx.erase(emm_ctx_it); - } - - ue_emm_ctx_t *ue_ptr = new ue_emm_ctx_t; - memcpy(ue_ptr,&ue_emm_ctx,sizeof(ue_emm_ctx)); - //This map will store UEs EMM context - m_imsi_to_ue_emm_ctx.insert(std::pair(ue_ptr->imsi,ue_ptr)); -} - */ - -/* - void - s1ap::add_new_ue_ecm_ctx(const ue_ecm_ctx_t &ue_ecm_ctx) - { - ue_ecm_ctx_t *ue_ptr = new ue_ecm_ctx_t; - memcpy(ue_ptr,&ue_ecm_ctx,sizeof(ue_ecm_ctx)); - - //This map will store UE's ECM context. - m_mme_ue_s1ap_id_to_ue_ecm_ctx.insert(std::pair(ue_ptr->mme_ue_s1ap_id,ue_ptr)); - //Store which enb currently holds the UE - std::map::iterator it_enb = m_sctp_to_enb_id.find(ue_ptr->enb_sri.sinfo_assoc_id); - uint16_t enb_id = it_enb->second; - std::map >::iterator it_ue_id = m_enb_id_to_ue_ids.find(enb_id); - if(it_ue_id==m_enb_id_to_ue_ids.end()) - { - m_s1ap_log->error("Could not find eNB's UEs\n"); - return; - } - it_ue_id->second.insert(ue_ptr->mme_ue_s1ap_id); - } - */ - /* -ue_emm_ctx_t* -s1ap::find_ue_emm_ctx_from_imsi(uint64_t imsi) -{ - std::map::iterator it = m_imsi_to_ue_emm_ctx.find(imsi); - if(it == m_imsi_to_ue_emm_ctx.end()) - { - return NULL; - } - else - { - return it->second; - } -} - -ue_ecm_ctx_t* -s1ap::find_ue_ecm_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id) -{ - std::map::iterator it = m_mme_ue_s1ap_id_to_ue_ecm_ctx.find(mme_ue_s1ap_id); - if(it == m_mme_ue_s1ap_id_to_ue_ecm_ctx.end()) - { - return NULL; - } - else - { - return it->second; - } -}*/ - /* -bool -s1ap::delete_ue_emm_ctx(uint64_t imsi) -{ - std::map::iterator ue_emm_ctx_it = m_imsi_to_ue_emm_ctx.find(imsi); - if(ue_emm_ctx_it == m_imsi_to_ue_emm_ctx.end()) - { - m_s1ap_log->info("Cannot delete UE EMM context, UE not found. IMSI: %d\n", imsi); - return false; - } - - //Delete UE context - m_imsi_to_ue_emm_ctx.erase(ue_emm_ctx_it); - delete ue_emm_ctx_it->second; - m_s1ap_log->info("Deleted UE EMM Context.\n"); - return true; -} - */ - /* -bool -s1ap::delete_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) -{ - std::map::iterator ue_ecm_ctx_it = m_mme_ue_s1ap_id_to_ue_ecm_ctx.find(mme_ue_s1ap_id); - if(ue_ecm_ctx_it == m_mme_ue_s1ap_id_to_ue_ecm_ctx.end()) - { - m_s1ap_log->info("Cannot delete UE ECM context, UE not found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); - return false; - } - ue_ecm_ctx_t* ue_ecm_ctx = ue_ecm_ctx_it->second; - - //Delete UE within eNB UE set - std::map::iterator it = m_sctp_to_enb_id.find(ue_ecm_ctx->enb_sri.sinfo_assoc_id); - if(it == m_sctp_to_enb_id.end() ) - { - m_s1ap_log->error("Could not find eNB for this request.\n"); - return false; - } - uint16_t enb_id = it->second; - std::map >::iterator ue_set = m_enb_id_to_ue_ids.find(enb_id); - if(ue_set == m_enb_id_to_ue_ids.end()) - { - m_s1ap_log->error("Could not find the eNB's UEs.\n"); - return false; - } - ue_set->second.erase(mme_ue_s1ap_id); - - //Delete UE context - m_mme_ue_s1ap_id_to_ue_ecm_ctx.erase(ue_ecm_ctx_it); - delete ue_ecm_ctx; - m_s1ap_log->info("Deleted UE ECM Context.\n"); - - return true; -} - */ From 58f204d94aca8bc2a4c5a6ed2df77466556c5a17 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 21:19:02 +0100 Subject: [PATCH 270/342] Set DEBUG constant for RelWithDebug --- CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 10952a010..a91e11da7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -257,9 +257,14 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -DDEBUG_MODE") else(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") + if(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG_MODE") + else(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") + endif(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") endif(${CMAKE_BUILD_TYPE} STREQUAL "Debug") + if (USE_LTE_RATES) message(STATUS "Using standard LTE sampling rates") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFORCE_STANDARD_RATE") From bd258372ea4453080af86ba72741bdde5277bdee Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 23:08:36 +0100 Subject: [PATCH 271/342] Fixes #164 --- lib/src/phy/phch/pbch.c | 61 +++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/lib/src/phy/phch/pbch.c b/lib/src/phy/phch/pbch.c index e7c0c33af..302ee9e7d 100644 --- a/lib/src/phy/phch/pbch.c +++ b/lib/src/phy/phch/pbch.c @@ -399,35 +399,41 @@ uint32_t srslte_pbch_crc_check(srslte_pbch_t *q, uint8_t *bits, uint32_t nof_por int decode_frame(srslte_pbch_t *q, uint32_t src, uint32_t dst, uint32_t n, uint32_t nof_bits, uint32_t nof_ports) { int j; - - memcpy(&q->temp[dst * nof_bits], &q->llr[src * nof_bits], - n * nof_bits * sizeof(float)); - /* descramble */ - srslte_scrambling_f_offset(&q->seq, &q->temp[dst * nof_bits], dst * nof_bits, - n * nof_bits); + if (dst + n <= 4 && src + n <= 4) { + memcpy(&q->temp[dst * nof_bits], &q->llr[src * nof_bits], + n * nof_bits * sizeof(float)); - for (j = 0; j < dst * nof_bits; j++) { - q->temp[j] = SRSLTE_RX_NULL; - } - for (j = (dst + n) * nof_bits; j < 4 * nof_bits; j++) { - q->temp[j] = SRSLTE_RX_NULL; - } + /* descramble */ + srslte_scrambling_f_offset(&q->seq, &q->temp[dst * nof_bits], dst * nof_bits, + n * nof_bits); - /* unrate matching */ - srslte_rm_conv_rx(q->temp, 4 * nof_bits, q->rm_f, SRSLTE_BCH_ENCODED_LEN); - - /* Normalize LLR */ - srslte_vec_sc_prod_fff(q->rm_f, 1.0/((float) 2*n), q->rm_f, SRSLTE_BCH_ENCODED_LEN); - - /* decode */ - srslte_viterbi_decode_f(&q->decoder, q->rm_f, q->data, SRSLTE_BCH_PAYLOADCRC_LEN); + for (j = 0; j < dst * nof_bits; j++) { + q->temp[j] = SRSLTE_RX_NULL; + } + for (j = (dst + n) * nof_bits; j < 4 * nof_bits; j++) { + q->temp[j] = SRSLTE_RX_NULL; + } + + /* unrate matching */ + srslte_rm_conv_rx(q->temp, 4 * nof_bits, q->rm_f, SRSLTE_BCH_ENCODED_LEN); - if (!srslte_pbch_crc_check(q, q->data, nof_ports)) { - return 1; + /* Normalize LLR */ + srslte_vec_sc_prod_fff(q->rm_f, 1.0/((float) 2*n), q->rm_f, SRSLTE_BCH_ENCODED_LEN); + + /* decode */ + srslte_viterbi_decode_f(&q->decoder, q->rm_f, q->data, SRSLTE_BCH_PAYLOADCRC_LEN); + + if (!srslte_pbch_crc_check(q, q->data, nof_ports)) { + return 1; + } else { + return SRSLTE_SUCCESS; + } } else { - return SRSLTE_SUCCESS; + fprintf(stderr, "Error in PBCH decoder: Invalid frame pointers dst=%d, src=%d, n=%d\n", src, dst, n); + return -1; } + } /* Decodes the PBCH channel @@ -514,7 +520,7 @@ int srslte_pbch_decode(srslte_pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[SRS for (nb = 0; nb < q->frame_idx; nb++) { for (dst = 0; (dst < 4 - nb); dst++) { for (src = 0; src < q->frame_idx - nb; src++) { - ret = decode_frame(q, src, dst, nb + 1, nof_bits, nant); + ret = decode_frame(q, src, dst, nb + 1, nof_bits, nant); if (ret == 1) { if (sfn_offset) { *sfn_offset = (int) dst - src + q->frame_idx - 1; @@ -526,15 +532,16 @@ int srslte_pbch_decode(srslte_pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[SRS memcpy(bch_payload, q->data, sizeof(uint8_t) * SRSLTE_BCH_PAYLOAD_LEN); } INFO("Decoded PBCH: src=%d, dst=%d, nb=%d, sfn_offset=%d\n", src, dst, nb+1, (int) dst - src + q->frame_idx - 1); - return 1; + srslte_pbch_decode_reset(q); + return 1; } } } } } nant++; - } while(nant <= q->cell.nof_ports); - + } while(nant <= q->cell.nof_ports); + /* If not found, make room for the next packet of radio frame symbols */ if (q->frame_idx == 4) { memmove(q->llr, &q->llr[nof_bits], nof_bits * 3 * sizeof(float)); From c850e2f87adab470c0692e5781b22a0a43d3a92b Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 23:08:51 +0100 Subject: [PATCH 272/342] Added check for issue #165 --- lib/src/common/pdu.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/src/common/pdu.cc b/lib/src/common/pdu.cc index 69c19518c..b3928f11b 100644 --- a/lib/src/common/pdu.cc +++ b/lib/src/common/pdu.cc @@ -120,8 +120,14 @@ uint8_t* sch_pdu::write_packet(srslte::log *log_h) { int init_rem_len=rem_len; sch_subh padding; - padding.set_padding(); - + padding.set_padding(); + + if (nof_subheaders <= 0) { + log_h->error("Writting PDU: nof_subheaders=%d\n", nof_subheaders); + log_h->console("Writting PDU: nof_subheaders=%d\n", nof_subheaders); + return NULL; + } + if (init_rem_len < 0) { log_h->error("init_rem_len=%d\n", init_rem_len); return NULL; From d66a455479bafe46141e4de4618a0dda65d6c621 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 14 Mar 2018 17:44:51 +0100 Subject: [PATCH 273/342] add check for invalid nof subheaders in MAC PDU --- lib/src/common/pdu.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/src/common/pdu.cc b/lib/src/common/pdu.cc index b3928f11b..b020cde81 100644 --- a/lib/src/common/pdu.cc +++ b/lib/src/common/pdu.cc @@ -132,7 +132,12 @@ uint8_t* sch_pdu::write_packet(srslte::log *log_h) log_h->error("init_rem_len=%d\n", init_rem_len); return NULL; } - + + if (nof_subheaders <= 0) { + log_h->error("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders); + return NULL; + } + /* If last SDU has zero payload, remove it. FIXME: Why happens this?? */ if (subheaders[nof_subheaders-1].get_payload_size() == 0) { del_subh(); From 25ccd296461ed8ce32044bbda200f8d02e3ff2bd Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 15 Mar 2018 09:59:39 +0100 Subject: [PATCH 274/342] fix issue when cell search doesn't set rx frequency because phy init takes too long See commit f3c04949b755ce135fef9488f213e3d7fed60b88 for reference and a more detailed description. --- srsue/src/phy/phch_recv.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 38dd5b561..4563c1476 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -280,10 +280,8 @@ void phch_recv::cell_search_inc() rrc->earfcn_end(); } else { Info("SYNC: Cell Search idx %d/%d\n", cur_earfcn_index, earfcn.size()); - if (current_earfcn != earfcn[cur_earfcn_index]) { - current_earfcn = earfcn[cur_earfcn_index]; - set_frequency(); - } + current_earfcn = earfcn[cur_earfcn_index]; + set_frequency(); phy_state = CELL_SEARCH; } } From 599cf9bc076ade9012602880df7e24a782beb64d Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 10:56:18 +0100 Subject: [PATCH 275/342] Resolved conflicting commits d66a455479bafe46141e4de4618a0dda65d6c621 and c850e2f87adab470c0692e5781b22a0a43d3a92b --- lib/src/common/pdu.cc | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/src/common/pdu.cc b/lib/src/common/pdu.cc index b020cde81..b0cdef638 100644 --- a/lib/src/common/pdu.cc +++ b/lib/src/common/pdu.cc @@ -123,8 +123,8 @@ uint8_t* sch_pdu::write_packet(srslte::log *log_h) padding.set_padding(); if (nof_subheaders <= 0) { - log_h->error("Writting PDU: nof_subheaders=%d\n", nof_subheaders); - log_h->console("Writting PDU: nof_subheaders=%d\n", nof_subheaders); + log_h->error("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders); + log_h->console("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders); return NULL; } @@ -133,11 +133,6 @@ uint8_t* sch_pdu::write_packet(srslte::log *log_h) return NULL; } - if (nof_subheaders <= 0) { - log_h->error("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders); - return NULL; - } - /* If last SDU has zero payload, remove it. FIXME: Why happens this?? */ if (subheaders[nof_subheaders-1].get_payload_size() == 0) { del_subh(); From f470645e9042c07fca26b635b770d82440b79832 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 10:56:46 +0100 Subject: [PATCH 276/342] Fix for real issue #164 --- lib/src/phy/phch/pbch.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/src/phy/phch/pbch.c b/lib/src/phy/phch/pbch.c index 302ee9e7d..722a28b4c 100644 --- a/lib/src/phy/phch/pbch.c +++ b/lib/src/phy/phch/pbch.c @@ -489,6 +489,8 @@ int srslte_pbch_decode(srslte_pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[SRS q->frame_idx++; ret = 0; + uint32_t frame_idx = q->frame_idx; + /* Try decoding for 1 to cell.nof_ports antennas */ if (q->search_all_ports) { nant = 1; @@ -498,7 +500,7 @@ int srslte_pbch_decode(srslte_pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[SRS do { if (nant != 3) { - DEBUG("Trying %d TX antennas with %d frames\n", nant, q->frame_idx); + DEBUG("Trying %d TX antennas with %d frames\n", nant, frame_idx); /* in control channels, only diversity is supported */ if (nant == 1) { @@ -511,19 +513,19 @@ int srslte_pbch_decode(srslte_pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[SRS } /* demodulate symbols */ - srslte_demod_soft_demodulate(SRSLTE_MOD_QPSK, q->d, &q->llr[nof_bits * (q->frame_idx - 1)], q->nof_symbols); + srslte_demod_soft_demodulate(SRSLTE_MOD_QPSK, q->d, &q->llr[nof_bits * (frame_idx - 1)], q->nof_symbols); /* We don't know where the 40 ms begin, so we try all combinations. E.g. if we received * 4 frames, try 1,2,3,4 individually, 12, 23, 34 in pairs, 123, 234 and finally 1234. * We know they are ordered. */ - for (nb = 0; nb < q->frame_idx; nb++) { + for (nb = 0; nb < frame_idx; nb++) { for (dst = 0; (dst < 4 - nb); dst++) { - for (src = 0; src < q->frame_idx - nb; src++) { + for (src = 0; src < frame_idx - nb; src++) { ret = decode_frame(q, src, dst, nb + 1, nof_bits, nant); if (ret == 1) { if (sfn_offset) { - *sfn_offset = (int) dst - src + q->frame_idx - 1; + *sfn_offset = (int) dst - src + frame_idx - 1; } if (nof_tx_ports) { *nof_tx_ports = nant; @@ -531,7 +533,7 @@ int srslte_pbch_decode(srslte_pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[SRS if (bch_payload) { memcpy(bch_payload, q->data, sizeof(uint8_t) * SRSLTE_BCH_PAYLOAD_LEN); } - INFO("Decoded PBCH: src=%d, dst=%d, nb=%d, sfn_offset=%d\n", src, dst, nb+1, (int) dst - src + q->frame_idx - 1); + INFO("Decoded PBCH: src=%d, dst=%d, nb=%d, sfn_offset=%d\n", src, dst, nb+1, (int) dst - src + frame_idx - 1); srslte_pbch_decode_reset(q); return 1; } From d873eaca5c0dd96827240bf7ab356df4d6d09b62 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 11:14:22 +0100 Subject: [PATCH 277/342] Assign same timer id after release (was not really a bug) --- lib/include/srslte/common/timers.h | 14 +++++++------- srsue/src/upper/rrc.cc | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/include/srslte/common/timers.h b/lib/include/srslte/common/timers.h index d77692d5a..7517aa751 100644 --- a/lib/include/srslte/common/timers.h +++ b/lib/include/srslte/common/timers.h @@ -151,15 +151,15 @@ public: fprintf(stderr, "Error getting unique timer id: no more timers available\n"); return 0; } else { - while(used_timers[next_timer]) { - next_timer++; - if (next_timer >= nof_timers) { - next_timer=0; + for (uint32_t i=0;itimer_get(active[measId].periodic_timer)->stop(); mac_timers->timer_release_id(active[measId].periodic_timer); - log_h->info("MEAS: Removed measId=%d\n", measId); + log_h->info("MEAS: Removed measId=%d, timer_id=%d\n", measId, active[measId].periodic_timer); active.erase(measId); } else { log_h->warning("MEAS: Removing unexistent measId=%d\n", measId); @@ -2846,7 +2846,7 @@ void rrc::rrc_meas::remove_meas_id(uint32_t measId) { void rrc::rrc_meas::remove_meas_id(std::map::iterator it) { mac_timers->timer_get(it->second.periodic_timer)->stop(); mac_timers->timer_release_id(it->second.periodic_timer); - log_h->info("MEAS: Removed measId=%d\n", it->first); + log_h->info("MEAS: Removed measId=%d, timer_id=%d\n", it->first, active[measId].periodic_timer); active.erase(it); } From 5342bb430e6016997dce5c97e4aced28e4adc175 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 11:15:33 +0100 Subject: [PATCH 278/342] previous commit not compiling --- srsue/src/upper/rrc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 6f2ede299..6c8ab63cc 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -2846,7 +2846,7 @@ void rrc::rrc_meas::remove_meas_id(uint32_t measId) { void rrc::rrc_meas::remove_meas_id(std::map::iterator it) { mac_timers->timer_get(it->second.periodic_timer)->stop(); mac_timers->timer_release_id(it->second.periodic_timer); - log_h->info("MEAS: Removed measId=%d, timer_id=%d\n", it->first, active[measId].periodic_timer); + log_h->info("MEAS: Removed measId=%d, timer_id=%d\n", it->first, it->second.periodic_timer); active.erase(it); } From 64cc34adb07477af00bfd369e41f13af6ea9cf18 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 11:31:09 +0100 Subject: [PATCH 279/342] previous commit not working --- lib/include/srslte/common/timers.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/include/srslte/common/timers.h b/lib/include/srslte/common/timers.h index 7517aa751..5e8b1cfd5 100644 --- a/lib/include/srslte/common/timers.h +++ b/lib/include/srslte/common/timers.h @@ -153,6 +153,7 @@ public: } else { for (uint32_t i=0;i Date: Thu, 15 Mar 2018 11:31:37 +0100 Subject: [PATCH 280/342] Revert "fix issue when cell search doesn't set rx frequency because phy init takes too long" This reverts commit 25ccd296461ed8ce32044bbda200f8d02e3ff2bd. --- srsue/src/phy/phch_recv.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 4563c1476..38dd5b561 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -280,8 +280,10 @@ void phch_recv::cell_search_inc() rrc->earfcn_end(); } else { Info("SYNC: Cell Search idx %d/%d\n", cur_earfcn_index, earfcn.size()); - current_earfcn = earfcn[cur_earfcn_index]; - set_frequency(); + if (current_earfcn != earfcn[cur_earfcn_index]) { + current_earfcn = earfcn[cur_earfcn_index]; + set_frequency(); + } phy_state = CELL_SEARCH; } } From df0dcb27e70a6867ac50aa179eb47a77eb8125f5 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 11:31:39 +0100 Subject: [PATCH 281/342] Revert "PHCH Receive is reset, the current EARFCN becomes the first one in the list." This reverts commit f3c04949b755ce135fef9488f213e3d7fed60b88. --- srsue/src/phy/phch_recv.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 38dd5b561..5821a1bf3 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -132,11 +132,7 @@ void phch_recv::reset() next_offset = 0; cell_is_set = false; srate_mode = SRATE_NONE; - if (!earfcn.empty()) { - current_earfcn = earfcn[0]; - } else { - current_earfcn = 0; - } + current_earfcn = 0; sfn_p.reset(); measure_p.reset(); search_p.reset(); From e845339d5406cc54e9b35fe343150e71078dcd00 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 11:41:49 +0100 Subject: [PATCH 282/342] rrc.connected() return true during HO --- srsue/src/ue.cc | 2 +- srsue/src/upper/rrc.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 1d83f087e..ca8c9002b 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -275,7 +275,7 @@ void ue::stop() bool ue::is_attached() { - return (RRC_STATE_CONNECTED == rrc.get_state()); + return rrc.is_connected(); } void ue::start_plot() { diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 6c8ab63cc..83d7174ca 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -156,7 +156,7 @@ rrc_state_t rrc::get_state() { } bool rrc::is_connected() { - return (RRC_STATE_CONNECTED == state); + return (RRC_STATE_CONNECTED >= state && state < RRC_STATE_LEAVE_CONNECTED); } bool rrc::have_drb() { From 86d4ce52e05255c64246f75317fe391aa0c80e8a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 12:27:55 +0100 Subject: [PATCH 283/342] Make intra-frequency measurement period/length a parameter --- lib/include/srslte/interfaces/ue_interfaces.h | 2 ++ srsue/hdr/phy/phch_recv.h | 2 -- srsue/src/main.cc | 8 ++++++++ srsue/src/phy/phch_recv.cc | 14 +++++++------- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index e69419983..bea0cb05c 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -494,6 +494,8 @@ typedef struct { bool sic_pss_enabled; float rx_gain_offset; bool pdsch_csi_enabled; + uint32_t intra_freq_meas_len_ms; + uint32_t intra_freq_meas_period_ms; } phy_args_t; diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index f955b30ce..378dfb8f9 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -233,8 +233,6 @@ private: void write(uint32_t tti, cf_t *data, uint32_t nsamples); private: void run_thread(); - const static int INTRA_FREQ_MEAS_LEN_MS = 20; - const static int INTRA_FREQ_MEAS_PERIOD_MS = 200; const static int INTRA_FREQ_MEAS_PRIO = DEFAULT_PRIORITY + 5; scell_recv scell; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 00fd23cf8..8753e7630 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -203,6 +203,14 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { bpo::value(&args->expert.phy.equalizer_mode)->default_value("mmse"), "Equalizer mode") + ("expert.intra_freq_meas_len_ms", + bpo::value(&args->expert.phy.intra_freq_meas_len_ms)->default_value(20), + "Duration of the intra-frequency neighbour cell measurement in ms.") + + ("expert.intra_freq_meas_period_ms", + bpo::value(&args->expert.phy.intra_freq_meas_period_ms)->default_value(200), + "Period of intra-frequency neighbour cell measurement in ms. Maximum as per 3GPP is 200 ms.") + ("expert.cfo_is_doppler", bpo::value(&args->expert.phy.cfo_is_doppler)->default_value(false), "Assume detected CFO is doppler and correct the UL in the same direction. If disabled, the CFO is assumed" diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 5821a1bf3..8227a2882 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1436,11 +1436,11 @@ void phch_recv::intra_measure::init(phch_common *common, rrc_interface_phy *rrc, receive_enabled = false; // Start scell - scell.init(log_h, common->args->sic_pss_enabled, INTRA_FREQ_MEAS_LEN_MS); + scell.init(log_h, common->args->sic_pss_enabled, common->args->intra_freq_meas_len_ms); - search_buffer = (cf_t*) srslte_vec_malloc(INTRA_FREQ_MEAS_LEN_MS*SRSLTE_SF_LEN_PRB(SRSLTE_MAX_PRB)*sizeof(cf_t)); + search_buffer = (cf_t*) srslte_vec_malloc(common->args->intra_freq_meas_len_ms*SRSLTE_SF_LEN_PRB(SRSLTE_MAX_PRB)*sizeof(cf_t)); - if (srslte_ringbuffer_init(&ring_buffer, sizeof(cf_t)*INTRA_FREQ_MEAS_LEN_MS*2*SRSLTE_SF_LEN_PRB(SRSLTE_MAX_PRB))) { + if (srslte_ringbuffer_init(&ring_buffer, sizeof(cf_t)*common->args->intra_freq_meas_len_ms*2*SRSLTE_SF_LEN_PRB(SRSLTE_MAX_PRB))) { return; } @@ -1510,7 +1510,7 @@ void phch_recv::intra_measure::rem_cell(int pci) { void phch_recv::intra_measure::write(uint32_t tti, cf_t *data, uint32_t nsamples) { if (receive_enabled) { - if ((tti%INTRA_FREQ_MEAS_PERIOD_MS) == 0) { + if ((tti%common->args->intra_freq_meas_period_ms) == 0) { receiving = true; receive_cnt = 0; measure_tti = tti; @@ -1522,7 +1522,7 @@ void phch_recv::intra_measure::write(uint32_t tti, cf_t *data, uint32_t nsamples receiving = false; } else { receive_cnt++; - if (receive_cnt == INTRA_FREQ_MEAS_LEN_MS) { + if (receive_cnt == common->args->intra_freq_meas_len_ms) { tti_sync.increase(); receiving = false; } @@ -1541,8 +1541,8 @@ void phch_recv::intra_measure::run_thread() if (running) { // Read data from buffer and find cells in it - srslte_ringbuffer_read(&ring_buffer, search_buffer, INTRA_FREQ_MEAS_LEN_MS*current_sflen*sizeof(cf_t)); - int found_cells = scell.find_cells(search_buffer, common->rx_gain_offset, primary_cell, INTRA_FREQ_MEAS_LEN_MS, info); + srslte_ringbuffer_read(&ring_buffer, search_buffer, common->args->intra_freq_meas_len_ms*current_sflen*sizeof(cf_t)); + int found_cells = scell.find_cells(search_buffer, common->rx_gain_offset, primary_cell, common->args->intra_freq_meas_len_ms, info); receiving = false; for (int i=0;i Date: Thu, 15 Mar 2018 16:05:36 +0000 Subject: [PATCH 284/342] Fixed bug with in GUTI attach with unkown M-TMSI. --- srsepc/src/mme/mme_gtpc.cc | 2 +- srsepc/src/mme/s1ap_nas_transport.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 53277e89c..e1a172600 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -216,7 +216,7 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu) //Save create session response info to E-RAB context ue_ctx_t *ue_ctx = m_s1ap->find_ue_ctx_from_imsi(imsi); if(ue_ctx == NULL){ - m_mme_gtpc_log->error("Could not find UE context\n"); + m_mme_gtpc_log->error("Could not find UE context. IMSI %015lu\n", imsi); return; } ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 135e99ae2..09affd296 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -950,8 +950,8 @@ s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ return false; } - //Store UE EMM context - //m_s1ap->add_new_ue_emm_ctx(ue_emm_ctx); + //Store UE context im IMSI map + m_s1ap->add_ue_ctx_to_imsi_map(ue_ctx); //Pack NAS Authentication Request in Downlink NAS Transport msg pack_authentication_request(reply_msg, ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, autn, rand); From 24b1096209bfb785625adb8381ca2899a728063e Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 18:35:40 +0100 Subject: [PATCH 285/342] Fixed bug in compute_ri() when passed NULL parameter causing segfault in MIMO --- srsue/src/phy/phch_worker.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index e613719cb..cb27a5000 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -418,7 +418,9 @@ void phch_worker::compute_ri(uint8_t *ri, uint8_t *pmi, float *sinr) { /* If 2 ort more receiving antennas, select RI */ float cn = 0.0f; srslte_ue_dl_ri_select(&ue_dl, ri, &cn); - Debug("TM3 RI select %d layers, κ=%fdB\n", (*ri) + 1, cn); + if (ri) { + Debug("TM3 RI select %d layers, κ=%fdB\n", (*ri) + 1, cn); + } } else { /* If only one receiving antenna, force RI for 1 layer */ if (ri) { From 622b3221d73dbf9ef067eb196d924e8caacbe67e Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 18:37:16 +0100 Subject: [PATCH 286/342] Don't restart RX stream when setting RX srate (causes UHD corruption in MIMO) --- lib/src/radio/radio.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index fc21b73be..7008790a3 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -301,9 +301,7 @@ void radio::set_master_clock_rate(double rate) void radio::set_rx_srate(double srate) { - srslte_rf_stop_rx_stream(&rf_device); srslte_rf_set_rx_srate(&rf_device, srate); - srslte_rf_start_rx_stream(&rf_device, false); } void radio::set_tx_freq(double freq) From d932a2ad8534d6a551d546795d5ca04af9533902 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 15 Mar 2018 20:04:50 +0000 Subject: [PATCH 287/342] Starting to add the ability to handle UE context release complete. --- srsepc/hdr/mme/s1ap_common.h | 1 + srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h | 1 + srsepc/src/mme/s1ap.cc | 3 ++ srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 57 +++++++++++++++++++++++++++ srsepc/src/mme/s1ap_nas_transport.cc | 21 +++++----- 5 files changed, 71 insertions(+), 12 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index adb9f68e0..9fea71d3f 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -140,6 +140,7 @@ typedef struct{ emm_state_t state; uint32_t mme_ue_s1ap_id; uint8_t attach_type; + struct in_addr ue_ip; srslte::gtpc_f_teid_ie sgw_ctrl_fteid; } ue_emm_ctx_t; diff --git a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h index 44458aea6..6fc599101 100644 --- a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h @@ -52,6 +52,7 @@ public: bool handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *in_ctxt_resp); bool handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ue_rel, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); bool send_ue_context_release_command(ue_ecm_ctx_t *ecm_ctx, srslte::byte_buffer_t *reply_buffer); + bool handle_ue_context_release_complete(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMPLETE_STRUCT *rel_comp); private: s1ap_ctx_mngmt_proc(); diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index e0f5e1422..efbe60c0a 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -283,6 +283,9 @@ s1ap::handle_successful_outcome(LIBLTE_S1AP_SUCCESSFULOUTCOME_STRUCT *msg) case LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_INITIALCONTEXTSETUPRESPONSE: m_s1ap_log->info("Received Initial Context Setup Response.\n"); return m_s1ap_ctx_mngmt_proc->handle_initial_context_setup_response(&msg->choice.InitialContextSetupResponse); + case LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_UECONTEXTRELEASECOMPLETE: + m_s1ap_log->info("Received UE Context Release Complete\n"); + return m_s1ap_ctx_mngmt_proc->handle_ue_context_release_complete(&msg->choice.UEContextReleaseComplete); default: m_s1ap_log->error("Unhandled successful outcome message: %s\n", liblte_s1ap_successfuloutcome_choice_text[msg->choice_type]); } diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 3485b6e2f..6f575efe4 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -349,5 +349,62 @@ s1ap_ctx_mngmt_proc::send_ue_context_release_command(ue_ecm_ctx_t *ecm_ctx, srsl return true; } +bool +s1ap_ctx_mngmt_proc::handle_ue_context_release_complete(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMPLETE_STRUCT *rel_comp) +{ + /* + typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; + LIBLTE_S1AP_USERLOCATIONINFORMATION_STRUCT UserLocationInformation; + bool UserLocationInformation_present; + }LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMPLETE_STRUCT; + */ + + uint32_t mme_ue_s1ap_id = rel_comp->MME_UE_S1AP_ID.MME_UE_S1AP_ID; + m_s1ap_log->info("Received UE Context Release Complete. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); + m_s1ap_log->console("Received UE Context Release Complete. MME-UE S1AP Id %d\n", mme_ue_s1ap_id); + + ue_ctx_t * ue_ctx = m_s1ap->find_ue_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); + if(ue_ctx == NULL) + { + m_s1ap_log->info("No UE context to release found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); + m_s1ap_log->console("No UE context to release found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); + return false; + } + ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; + + //Delete user plane context at the SPGW (but keep GTP-C connection). + if (ecm_ctx->state == ECM_STATE_CONNECTED) + { + //There are active E-RABs, send release access mearers request + m_s1ap_log->console("There are active E-RABs, send release access mearers request"); + m_s1ap_log->info("There are active E-RABs, send release access mearers request"); + m_mme_gtpc->send_release_access_bearers_request(ecm_ctx->imsi); + //The handle_releease_access_bearers_response function will make sure to mark E-RABS DEACTIVATED + //It will release the UEs downstream S1-u and keep the upstream S1-U connection active. + } + else + { + //No ECM Context to release + m_s1ap_log->info("UE is not ECM connected. No need to release S1-U. MME UE S1AP Id %d\n", mme_ue_s1ap_id); + m_s1ap_log->console("UE is not ECM connected. No need to release S1-U. MME UE S1AP Id %d\n", mme_ue_s1ap_id); + //Make sure E-RABS are merked as DEACTIVATED. + for(int i=0;ierabs_ctx[i].state = ERAB_DEACTIVATED; + } + } + + //Delete UE context + m_s1ap->release_ue_ecm_ctx(ue_ctx->ecm_ctx.mme_ue_s1ap_id); + m_s1ap_log->info("UE Context Release Completed.\n"); + m_s1ap_log->console("UE Context Release Completed.\n"); + return true; +} + } //namespace srsepc diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 09affd296..103d9f492 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -699,12 +699,14 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, //Save whether secure ESM information transfer is necessary ecm_ctx->eit = false; - //Initialize E-RABs - for(uint i = 0 ; i< MAX_ERABS_PER_UE; i++) + //Get UE IP, and uplink F-TEID + if(emm_ctx->ue_ip.s_addr == 0 ) { - ecm_ctx->erabs_ctx[i].state = ERAB_DEACTIVATED; - ecm_ctx->erabs_ctx[i].erab_id = i; + m_s1ap_log->error("UE has no valid IP assigned upon reception of service request"); } + + m_s1ap_log->console("UE previously assigned IP: %s",inet_ntoa(emm_ctx->ue_ip)); + //Mark E-RABs as setup, but not active yet //Re-generate K_eNB liblte_security_generate_k_enb(emm_ctx->security_ctxt.k_asme, emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.k_enb); @@ -932,16 +934,11 @@ s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ m_s1ap_log->info("Id Response -- IMSI: %015lu\n", imsi); m_s1ap_log->console("Id Response -- IMSI: %015lu\n", imsi); - ecm_ctx->imsi = imsi; - //Get UE EMM context - //if(m_s1ap->get_tmp_ue_emm_ctx(ue_ecm_ctx->mme_ue_s1ap_id, &ue_emm_ctx) == false) - //{ - // m_s1ap_log->error("Could not find UE's temporary EMM context. MME UE S1AP Id: %d\n",ue_ecm_ctx->mme_ue_s1ap_id); - // return false; - //} + //Set UE's context IMSI emm_ctx->imsi=imsi; - + ecm_ctx->imsi = imsi; + //Get Authentication Vectors from HSS if(!m_hss->gen_auth_info_answer(imsi, emm_ctx->security_ctxt.k_asme, autn, rand, emm_ctx->security_ctxt.xres)) { From 548a4ae29d02cfad20f6f14b14bae045a9ad91a7 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 16 Mar 2018 11:22:40 +0100 Subject: [PATCH 288/342] RRC is_connected return and srsgui crashing if ports=0 when init --- srsue/hdr/phy/phch_worker.h | 12 ++++++++++-- srsue/src/upper/rrc.cc | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index e87603e5d..28c4715ad 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -63,8 +63,16 @@ public: void write_trace(std::string filename); int read_ce_abs(float *ce_abs, uint32_t tx_antenna, uint32_t rx_antenna); - uint32_t get_cell_nof_ports() {return cell.nof_ports;}; - uint32_t get_rx_nof_antennas() {return ue_dl.nof_rx_antennas;}; + uint32_t get_cell_nof_ports() { + if (cell_initiated) { + return cell.nof_ports; + } else { + return 1; + } + }; + uint32_t get_rx_nof_antennas() { + return ue_dl.nof_rx_antennas; + }; int read_pdsch_d(cf_t *pdsch_d); void start_plot(); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 83d7174ca..e419ea710 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -156,7 +156,7 @@ rrc_state_t rrc::get_state() { } bool rrc::is_connected() { - return (RRC_STATE_CONNECTED >= state && state < RRC_STATE_LEAVE_CONNECTED); + return (state >= RRC_STATE_CONNECTED && state < RRC_STATE_LEAVE_CONNECTED); } bool rrc::have_drb() { From 321a750f561d276d0bbe8a4b066ff239a735f7be Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 16 Mar 2018 11:23:10 +0100 Subject: [PATCH 289/342] Added features to ringbuffer --- lib/include/srslte/phy/utils/ringbuffer.h | 2 ++ lib/src/phy/utils/ringbuffer.c | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/include/srslte/phy/utils/ringbuffer.h b/lib/include/srslte/phy/utils/ringbuffer.h index b8d0cd5c9..a93ebf181 100644 --- a/lib/include/srslte/phy/utils/ringbuffer.h +++ b/lib/include/srslte/phy/utils/ringbuffer.h @@ -28,6 +28,8 @@ SRSLTE_API void srslte_ringbuffer_reset(srslte_ringbuffer_t *q); SRSLTE_API int srslte_ringbuffer_status(srslte_ringbuffer_t *q); +SRSLTE_API int srslte_ringbuffer_space(srslte_ringbuffer_t *q); + SRSLTE_API int srslte_ringbuffer_write(srslte_ringbuffer_t *q, void *ptr, int nof_bytes); diff --git a/lib/src/phy/utils/ringbuffer.c b/lib/src/phy/utils/ringbuffer.c index 8f0c3edf2..02b98a4d8 100644 --- a/lib/src/phy/utils/ringbuffer.c +++ b/lib/src/phy/utils/ringbuffer.c @@ -13,11 +13,10 @@ int srslte_ringbuffer_init(srslte_ringbuffer_t *q, int capacity) } q->active = true; q->capacity = capacity; - srslte_ringbuffer_reset(q); - pthread_mutex_init(&q->mutex, NULL); pthread_cond_init(&q->cvar, NULL); - + srslte_ringbuffer_reset(q); + return 0; } @@ -48,6 +47,11 @@ int srslte_ringbuffer_status(srslte_ringbuffer_t *q) return q->count; } +int srslte_ringbuffer_space(srslte_ringbuffer_t *q) +{ + return q->capacity - q->count; +} + int srslte_ringbuffer_write(srslte_ringbuffer_t *q, void *p, int nof_bytes) { uint8_t *ptr = (uint8_t*) p; From 04d5676db027fbec32ef2d55b93c3e1b6339de6b Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 16 Mar 2018 12:55:58 +0000 Subject: [PATCH 290/342] Fixed bug to save UE ctx on the mme_ue_s1ap_id_map upon reception of the service request. Service request is now working again for the case where the UE is ECM-IDLE. --- srsepc/src/mme/mme_gtpc.cc | 3 +++ srsepc/src/mme/s1ap_nas_transport.cc | 3 +++ 2 files changed, 6 insertions(+) diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index e1a172600..c5698af95 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -222,6 +222,9 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu) ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; + //Save UE IP to nas ctxt + emm_ctx->ue_ip.s_addr = cs_resp->paa.ipv4; + m_mme_gtpc_log->console("SPGW Allocated IP %s to ISMI %015lu",inet_ntoa(emm_ctx->ue_ip),emm_ctx->imsi); //Save SGW ctrl F-TEID in GTP-C context std::map::iterator it_g = m_imsi_to_gtpc_ctx.find(imsi); if(it_g == m_imsi_to_gtpc_ctx.end()) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 103d9f492..1eece94a4 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -712,6 +712,9 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, liblte_security_generate_k_enb(emm_ctx->security_ctxt.k_asme, emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.k_enb); m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",emm_ctx->security_ctxt.ul_nas_count); m_s1ap_log->console("UE Ctr TEID %d\n", emm_ctx->sgw_ctrl_fteid.teid); + + //Save UE ctx to MME UE S1AP id + m_s1ap->add_ue_ctx_to_mme_ue_s1ap_id_map(ue_ctx); m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx,&ecm_ctx->erabs_ctx[5]); } else From 0f45369d44cec4358d0851bb81fcaf52cbb9f5ed Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 16 Mar 2018 15:07:23 +0000 Subject: [PATCH 291/342] Trying to fix service request when ECM content is present. --- srsepc/src/mme/mme_gtpc.cc | 2 +- srsepc/src/mme/s1ap_nas_transport.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index c5698af95..a27e12a4d 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -224,7 +224,7 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu) //Save UE IP to nas ctxt emm_ctx->ue_ip.s_addr = cs_resp->paa.ipv4; - m_mme_gtpc_log->console("SPGW Allocated IP %s to ISMI %015lu",inet_ntoa(emm_ctx->ue_ip),emm_ctx->imsi); + m_mme_gtpc_log->console("SPGW Allocated IP %s to ISMI %015lu\n",inet_ntoa(emm_ctx->ue_ip),emm_ctx->imsi); //Save SGW ctrl F-TEID in GTP-C context std::map::iterator it_g = m_imsi_to_gtpc_ctx.find(imsi); if(it_g == m_imsi_to_gtpc_ctx.end()) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 1eece94a4..df31dfdc6 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -676,9 +676,9 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, //Delete eNB context and connect. m_s1ap_log->console("Service Request -- User has ECM context already\n"); m_s1ap_log->info("Service Request -- User has ECM context already\n"); - m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); + //m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); //int default_bearer_id = 5; - //m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[default_bearer_id]); + m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[5]); //FIXME Send Modify context request OR send ctx release command and wait for the reply. } else if(ecm_ctx->state == ECM_STATE_IDLE) From 682ed433b212b7b0aee682cacb3c2831f3f7260c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 18 Mar 2018 13:24:09 +0100 Subject: [PATCH 292/342] Possible fix to #167 --- lib/include/srslte/common/pdu.h | 11 ++++++++--- lib/src/common/pdu.cc | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/include/srslte/common/pdu.h b/lib/include/srslte/common/pdu.h index 5d37a0d63..20fe91816 100644 --- a/lib/include/srslte/common/pdu.h +++ b/lib/include/srslte/common/pdu.h @@ -133,11 +133,16 @@ public: // Section 6.1.2 void parse_packet(uint8_t *ptr) { uint8_t *init_ptr = ptr; - nof_subheaders = 0; - while(subheaders[nof_subheaders].read_subheader(&ptr)) { + nof_subheaders = 0; + bool ret = false; + do { + if (nof_subheaders < (int) max_subheaders) { + ret = subheaders[nof_subheaders].read_subheader(&ptr); + } + } while (ret && nof_subheaders < (int) max_subheaders); + if (nof_subheaders + 1 < (int) max_subheaders) { nof_subheaders++; } - nof_subheaders++; for (int i=0;ierror("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders); log_h->console("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders); return NULL; From 37e06d78ead5e87d3050fb57d2aa1251ecfed91f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 19 Mar 2018 13:21:36 +0100 Subject: [PATCH 293/342] fix build_mode printing in RelWithDebInfo mode --- CMakeLists.txt | 16 ++++++---------- lib/include/srslte/build_info.h.in | 12 ++++++++++-- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a91e11da7..98023d7b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -231,12 +231,6 @@ endmacro(ADD_CXX_COMPILER_FLAG_IF_AVAILABLE) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${GCC_ARCH} -Wall -Wno-comment -Wno-reorder -Wno-unused-but-set-variable -Wno-unused-variable -std=c++03") - if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -DDEBUG_MODE") - else(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") - endif(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - find_package(SSE) if (HAVE_AVX2) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse -mavx2 -DLV_HAVE_AVX2 -DLV_HAVE_AVX -DLV_HAVE_SSE") @@ -255,16 +249,18 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=${GCC_ARCH} -Wall -Wno-comment -Wno-write-strings -Wno-format-extra-args -Winline -Wno-unused-result -Wno-format -std=c99 -D_GNU_SOURCE") if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -DDEBUG_MODE") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb -O0 -DDEBUG_MODE -DBUILD_TYPE_DEBUG") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -O0 -DDEBUG_MODE -DBUILD_TYPE_DEBUG") else(${CMAKE_BUILD_TYPE} STREQUAL "Debug") if(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG_MODE") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb -DBUILD_TYPE_RELWITHDEBINFO") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -DBUILD_TYPE_RELWITHDEBINFO") else(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -DBUILD_TYPE_RELEASE") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -DBUILD_TYPE_RELEASE") endif(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") endif(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - if (USE_LTE_RATES) message(STATUS "Using standard LTE sampling rates") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFORCE_STANDARD_RATE") diff --git a/lib/include/srslte/build_info.h.in b/lib/include/srslte/build_info.h.in index a8acb306b..90dac1dbb 100644 --- a/lib/include/srslte/build_info.h.in +++ b/lib/include/srslte/build_info.h.in @@ -32,10 +32,18 @@ extern "C" { # endif -#ifdef NDEBUG - static char build_mode[] = "Release"; +#ifdef BUILD_TYPE_RELEASE + static char build_mode[] = "Release"; #else + #ifdef BUILD_TYPE_DEBUG static char build_mode[] = "Debug"; + #else + #ifdef BUILD_TYPE_RELWITHDEBINFO + static char build_mode[] = "RelWithDebInfo"; + #else + static char build_mode[] = "unknown"; + #endif + #endif #endif // the configured build options for srsLTE From 8b04d7c308e707536ab02d291d83062b55f311f0 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 19 Mar 2018 13:25:33 +0100 Subject: [PATCH 294/342] fix compile warning --- srsue/src/phy/phch_recv.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 8227a2882..0df792fd5 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1150,7 +1150,7 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in offset = found_best?best_test_offset:offset; #endif - if (offset >= 0 && offset < (int) sf_len*max_sf) { + if (offset >= 0 && offset < (int)(sf_len*max_sf)) { uint32_t nof_sf = (sf_len*max_sf - offset)/sf_len; From c5b423ffee5e852a5e4c82c6369fbf409d59243b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 19 Mar 2018 14:38:27 +0100 Subject: [PATCH 295/342] fix subheader parsing --- lib/include/srslte/common/pdu.h | 9 ++++----- lib/src/common/pdu.cc | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/include/srslte/common/pdu.h b/lib/include/srslte/common/pdu.h index 20fe91816..5d0f5a235 100644 --- a/lib/include/srslte/common/pdu.h +++ b/lib/include/srslte/common/pdu.h @@ -136,13 +136,12 @@ public: nof_subheaders = 0; bool ret = false; do { - if (nof_subheaders < (int) max_subheaders) { + if (nof_subheaders < (int)max_subheaders) { ret = subheaders[nof_subheaders].read_subheader(&ptr); + nof_subheaders++; } - } while (ret && nof_subheaders < (int) max_subheaders); - if (nof_subheaders + 1 < (int) max_subheaders) { - nof_subheaders++; - } + } while (ret && (nof_subheaders + 1) < (int)max_subheaders); + for (int i=0;ierror("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders); log_h->console("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders); return NULL; From daf0a113456c4dac4311ef9b3f7e5c8b7fd69b2c Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Tue, 20 Mar 2018 12:47:00 +0000 Subject: [PATCH 296/342] Fix for RRC Connection Reject wait time pack/unpack --- lib/src/asn1/liblte_rrc.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/asn1/liblte_rrc.cc b/lib/src/asn1/liblte_rrc.cc index c53399384..74beb46cf 100644 --- a/lib/src/asn1/liblte_rrc.cc +++ b/lib/src/asn1/liblte_rrc.cc @@ -11771,7 +11771,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_rrc_connection_reject_msg(LIBLTE_RRC_CONNECTIO liblte_value_2_bits(0, &msg_ptr, 1); // Wait Time - liblte_value_2_bits(con_rej->wait_time, &msg_ptr, 4); + liblte_value_2_bits(con_rej->wait_time - 1, &msg_ptr, 4); // Fill in the number of bits used msg->N_bits = msg_ptr - msg->msg; @@ -11800,7 +11800,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_reject_msg(LIBLTE_BIT_MSG_STR liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; // Wait Time - con_rej->wait_time = liblte_bits_2_value(&msg_ptr, 4); + con_rej->wait_time = liblte_bits_2_value(&msg_ptr, 4) + 1; liblte_rrc_consume_noncrit_extension(ext, __func__, &msg_ptr); From 50aeda200966a22ceb60fcfaf217c15757a95d3f Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 20 Mar 2018 14:52:34 +0000 Subject: [PATCH 297/342] Fixed bug in SPGW when replacing an existing eNB S1-U TEID. Service request seems to be working for the cases of ECM idle and ECM connected. --- srsepc/src/mme/s1ap_nas_transport.cc | 30 ++++++++++++++++------------ srsepc/src/spgw/spgw.cc | 4 +++- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index df31dfdc6..ff95a7624 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -667,22 +667,26 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, { m_s1ap_log->error("Service Request -- User is ECM CONNECTED\n"); - //Service request to Connected UE. + //Release previous context + m_s1ap_log->info("Service Request -- Releasing previouse ECM context. eNB S1AP Id %d, MME UE S1AP Id %d\n", ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id); + m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); + m_s1ap->release_ue_ecm_ctx(ecm_ctx->mme_ue_s1ap_id); + } + //Handle service request from Connected UE. //Set eNB UE S1ap identity - ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; - m_s1ap_log->console("Service Request -- eNB UE S1AP Id %d \n", enb_ue_s1ap_id); - m_s1ap_log->info("Service Request -- eNB UE S1AP Id %d\n ", enb_ue_s1ap_id); + // ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + // m_s1ap_log->console("Service Request -- eNB UE S1AP Id %d \n", enb_ue_s1ap_id); + //m_s1ap_log->info("Service Request -- eNB UE S1AP Id %d\n ", enb_ue_s1ap_id); //Delete eNB context and connect. - m_s1ap_log->console("Service Request -- User has ECM context already\n"); - m_s1ap_log->info("Service Request -- User has ECM context already\n"); + //m_s1ap_log->console("Service Request -- User has ECM context already\n"); + //m_s1ap_log->info("Service Request -- User has ECM context already\n"); //m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); //int default_bearer_id = 5; - m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[5]); - //FIXME Send Modify context request OR send ctx release command and wait for the reply. - } - else if(ecm_ctx->state == ECM_STATE_IDLE) - { + //m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[5]); + //} + //else if(ecm_ctx->state == ECM_STATE_IDLE) + //{ ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; //UE not connect. Connect normally. @@ -716,12 +720,12 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, //Save UE ctx to MME UE S1AP id m_s1ap->add_ue_ctx_to_mme_ue_s1ap_id_map(ue_ctx); m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx,&ecm_ctx->erabs_ctx[5]); - } + /*} else { m_s1ap_log->console("ECM context is un-initialized.\n"); m_s1ap_log->error("ECM context is un-initialized.\n"); - } + }*/ } else { diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index 0acb37041..28dada151 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -593,8 +593,10 @@ spgw::handle_modify_bearer_request(struct srslte::gtpc_pdu *mb_req_pdu, struct s m_spgw_log->info("eNB Rx User TEID 0x%x, eNB Rx User IP %s\n", tunnel_ctx->dw_user_fteid.teid, inet_ntoa(addr3)); //Setup IP to F-TEID map + //bool ret = false; pthread_mutex_lock(&m_mutex); - m_ip_to_teid.insert(std::pair(tunnel_ctx->ue_ipv4, tunnel_ctx->dw_user_fteid)); + m_ip_to_teid[tunnel_ctx->ue_ipv4]=tunnel_ctx->dw_user_fteid; + //ret = m_ip_to_teid.insert(std::pair(tunnel_ctx->ue_ipv4, tunnel_ctx->dw_user_fteid)); pthread_mutex_unlock(&m_mutex); //Setting up Modify bearer response PDU From acc4f925bc43870a75e55d0405c006f1970b039d Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 20 Mar 2018 16:35:01 +0000 Subject: [PATCH 298/342] getting rid of boost::mutex on MME GTPc entity --- srsepc/src/mme/mme_gtpc.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index a27e12a4d..e25ea05d1 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -33,7 +33,8 @@ namespace srsepc{ mme_gtpc* mme_gtpc::m_instance = NULL; -boost::mutex mme_gtpc_instance_mutex; +pthread_mutex_t mme_gtpc_instance_mutex = PTHREAD_MUTEX_INITIALIZER; + mme_gtpc::mme_gtpc() { @@ -46,21 +47,23 @@ mme_gtpc::~mme_gtpc() mme_gtpc* mme_gtpc::get_instance(void) { - boost::mutex::scoped_lock lock(mme_gtpc_instance_mutex); + pthread_mutex_lock(&mme_gtpc_instance_mutex); if(NULL == m_instance) { m_instance = new mme_gtpc(); } + pthread_mutex_unlock(&mme_gtpc_instance_mutex); return(m_instance); } void mme_gtpc::cleanup(void) { - boost::mutex::scoped_lock lock(mme_gtpc_instance_mutex); + pthread_mutex_lock(&mme_gtpc_instance_mutex); if(NULL != m_instance) { delete m_instance; m_instance = NULL; } + pthread_mutex_unlock(&mme_gtpc_instance_mutex); } From 2ab25f4c1b55a4a1b2217acf0b8420a1b22dec02 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 20 Mar 2018 16:35:35 +0000 Subject: [PATCH 299/342] Getting rid of debug prints. --- srsepc/src/spgw/spgw.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index 2ef6facc0..f54eef7df 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -340,7 +340,7 @@ spgw::handle_sgi_pdu(srslte::byte_buffer_t *msg) dest_addr.s_addr = dest_ip; //m_spgw_log->console("IP version: %d\n", version); - m_spgw_log->console("Received packet to IP: %s\n", inet_ntoa(dest_addr)); + //m_spgw_log->console("Received packet to IP: %s\n", inet_ntoa(dest_addr)); pthread_mutex_lock(&m_mutex); gtp_fteid_it = m_ip_to_teid.find(dest_ip); @@ -353,7 +353,7 @@ spgw::handle_sgi_pdu(srslte::byte_buffer_t *msg) if(ip_found == false) { - m_spgw_log->console("IP Packet is not for any UE\n"); + //m_spgw_log->console("IP Packet is not for any UE\n"); return; } struct sockaddr_in enb_addr; From 1dd87e51133af37c4072082baf8f86828605dc27 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 20 Mar 2018 16:53:11 +0000 Subject: [PATCH 300/342] Getting rid of boost::mutext on enb singleton class --- srsenb/src/enb.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index e440081d0..564775e5e 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -32,26 +32,27 @@ namespace srsenb { enb* enb::instance = NULL; -boost::mutex enb_instance_mutex; - +pthread_mutex_t enb_instance_mutex = PTHREAD_MUTEX_INITIALIZER; enb* enb::get_instance(void) { - boost::mutex::scoped_lock lock(enb_instance_mutex); + pthread_mutex_lock(&enb_instance_mutex); if(NULL == instance) { - instance = new enb(); + instance = new enb(); } + pthread_mutex_unlock(&enb_instance_mutex); return(instance); } void enb::cleanup(void) { srslte_dft_exit(); srslte::byte_buffer_pool::cleanup(); - boost::mutex::scoped_lock lock(enb_instance_mutex); + pthread_mutex_lock(&enb_instance_mutex); if(NULL != instance) { delete instance; instance = NULL; } + pthread_mutex_unlock(&enb_instance_mutex); } enb::enb() : started(false) { From 2d9c10102714b4fbb1b5dbe46346712331f9257b Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 21 Mar 2018 11:42:37 +0100 Subject: [PATCH 301/342] Check all DRB config parameters --- srsenb/src/enb_cfg_parser.cc | 48 +++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 669d2586b..b63c46058 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -1072,7 +1072,9 @@ int field_qci::parse(libconfig::Setting &root) parser::field_enum_num sn_field_len ("sn_field_length", &rlc_cfg->sn_field_len, liblte_rrc_sn_field_length_num, LIBLTE_RRC_SN_FIELD_LENGTH_N_ITEMS); - sn_field_len.parse(q["rlc_config"]["ul_um"]); + if (sn_field_len.parse(q["rlc_config"]["ul_um"])) { + fprintf(stderr, "Error can't find sn_field_length in section ul_um\n"); + } } if (q["rlc_config"].exists("dl_um")) { @@ -1085,12 +1087,16 @@ int field_qci::parse(libconfig::Setting &root) parser::field_enum_num sn_field_len ("sn_field_length", &rlc_cfg->sn_field_len, liblte_rrc_sn_field_length_num, LIBLTE_RRC_SN_FIELD_LENGTH_N_ITEMS); - sn_field_len.parse(q["rlc_config"]["dl_um"]); + if (sn_field_len.parse(q["rlc_config"]["dl_um"])) { + fprintf(stderr, "Error can't find sn_field_length in section dl_um\n"); + } parser::field_enum_num t_reordering ("t_reordering", &rlc_cfg->t_reordering, liblte_rrc_t_reordering_num, LIBLTE_RRC_T_REORDERING_N_ITEMS); - t_reordering.parse(q["rlc_config"]["dl_um"]); + if (t_reordering.parse(q["rlc_config"]["dl_um"])) { + fprintf(stderr, "Error can't find t_reordering in section dl_um\n"); + } } // Parse RLC-AM section @@ -1100,22 +1106,30 @@ int field_qci::parse(libconfig::Setting &root) parser::field_enum_num t_poll_retx ("t_poll_retx", &rlc_cfg->t_poll_retx, liblte_rrc_t_poll_retransmit_num, LIBLTE_RRC_T_POLL_RETRANSMIT_N_ITEMS); - t_poll_retx.parse(q["rlc_config"]["ul_am"]); + if (t_poll_retx.parse(q["rlc_config"]["ul_am"])) { + fprintf(stderr, "Error can't find t_poll_retx in section ul_am\n"); + } parser::field_enum_num poll_pdu ("poll_pdu", &rlc_cfg->poll_pdu, liblte_rrc_poll_pdu_num, LIBLTE_RRC_POLL_PDU_N_ITEMS); - poll_pdu.parse(q["rlc_config"]["ul_am"]); + if (poll_pdu.parse(q["rlc_config"]["ul_am"])) { + fprintf(stderr, "Error can't find poll_pdu in section ul_am\n"); + } parser::field_enum_num poll_byte ("poll_byte", &rlc_cfg->poll_byte, liblte_rrc_poll_byte_num, LIBLTE_RRC_POLL_BYTE_N_ITEMS); - poll_byte.parse(q["rlc_config"]["ul_am"]); + if (poll_byte.parse(q["rlc_config"]["ul_am"])) { + fprintf(stderr, "Error can't find poll_byte in section ul_am\n"); + } parser::field_enum_num max_retx_thresh ("max_retx_thresh", &rlc_cfg->max_retx_thresh, liblte_rrc_max_retx_threshold_num, LIBLTE_RRC_MAX_RETX_THRESHOLD_N_ITEMS); - max_retx_thresh.parse(q["rlc_config"]["ul_am"]); + if (max_retx_thresh.parse(q["rlc_config"]["ul_am"])) { + fprintf(stderr, "Error can't find max_retx_thresh in section ul_am\n"); + } } if (q["rlc_config"].exists("dl_am")) { @@ -1124,12 +1138,16 @@ int field_qci::parse(libconfig::Setting &root) parser::field_enum_num t_reordering ("t_reordering", &rlc_cfg->t_reordering, liblte_rrc_t_reordering_num, LIBLTE_RRC_T_REORDERING_N_ITEMS); - t_reordering.parse(q["rlc_config"]["dl_am"]); + if (t_reordering.parse(q["rlc_config"]["dl_am"])) { + fprintf(stderr, "Error can't find t_reordering in section dl_am\n"); + } parser::field_enum_num t_status_prohibit ("t_status_prohibit", &rlc_cfg->t_status_prohibit, liblte_rrc_t_status_prohibit_num, LIBLTE_RRC_T_STATUS_PROHIBIT_N_ITEMS); - t_status_prohibit.parse(q["rlc_config"]["dl_am"]); + if (t_status_prohibit.parse(q["rlc_config"]["dl_am"])) { + fprintf(stderr, "Error can't find t_status_prohibit in section dl_am\n"); + } } @@ -1141,17 +1159,23 @@ int field_qci::parse(libconfig::Setting &root) LIBLTE_RRC_UL_SPECIFIC_PARAMETERS_STRUCT *lc_cfg = &cfg[qci].lc_cfg; parser::field priority ("priority", &lc_cfg->priority); - priority.parse(q["logical_channel_config"]); + if (priority.parse(q["logical_channel_config"])) { + fprintf(stderr, "Error can't find logical_channel_config in section priority\n"); + } parser::field_enum_num prioritized_bit_rate ("prioritized_bit_rate", &lc_cfg->prioritized_bit_rate, liblte_rrc_prioritized_bit_rate_num, LIBLTE_RRC_PRIORITIZED_BIT_RATE_N_ITEMS); - prioritized_bit_rate.parse(q["logical_channel_config"]); + if (prioritized_bit_rate.parse(q["logical_channel_config"])) { + fprintf(stderr, "Error can't find prioritized_bit_rate in section logical_channel_config\n"); + } parser::field_enum_num bucket_size_duration ("bucket_size_duration", &lc_cfg->bucket_size_duration, liblte_rrc_bucket_size_duration_num, LIBLTE_RRC_BUCKET_SIZE_DURATION_N_ITEMS); - bucket_size_duration.parse(q["logical_channel_config"]); + if (bucket_size_duration.parse(q["logical_channel_config"])) { + fprintf(stderr, "Error can't find bucket_size_duration in section logical_channel_config\n"); + } parser::field log_chan_group ("log_chan_group", &lc_cfg->log_chan_group); if (log_chan_group.parse(q["logical_channel_config"])) { From f4243656c913369b6d9acdcae0653862103c1626 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 21 Mar 2018 11:47:30 +0100 Subject: [PATCH 302/342] Check integrity_generate msg_size parameter --- srsue/src/upper/nas.cc | 90 +++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 27 deletions(-) diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 763515ea4..7069f4a23 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -345,30 +345,38 @@ void nas::integrity_generate(uint8_t *key_128, bool nas::integrity_check(byte_buffer_t *pdu) { - uint8_t exp_mac[4]; - uint8_t *mac = &pdu->msg[1]; - int i; + if (!pdu) { + nas_log->error("Invalid PDU\n"); + return NULL; + } + if (pdu->N_bytes > 5) { + uint8_t exp_mac[4]; + uint8_t *mac = &pdu->msg[1]; + int i; - integrity_generate(&k_nas_int[16], - ctxt.rx_count, - SECURITY_DIRECTION_DOWNLINK, - &pdu->msg[5], - pdu->N_bytes-5, - &exp_mac[0]); - - // Check if expected mac equals the sent mac - for(i=0; i<4; i++){ - if(exp_mac[i] != mac[i]){ - nas_log->warning("Integrity check failure. Local: count=%d, [%02x %02x %02x %02x], " - "Received: count=%d, [%02x %02x %02x %02x]\n", - ctxt.rx_count, exp_mac[0], exp_mac[1], exp_mac[2], exp_mac[3], - pdu->msg[5], mac[0], mac[1], mac[2], mac[3]); - return false; + integrity_generate(&k_nas_int[16], + ctxt.rx_count, + SECURITY_DIRECTION_DOWNLINK, + &pdu->msg[5], + pdu->N_bytes-5, + &exp_mac[0]); + + // Check if expected mac equals the sent mac + for(i=0; i<4; i++){ + if(exp_mac[i] != mac[i]){ + nas_log->warning("Integrity check failure. Local: count=%d, [%02x %02x %02x %02x], " + "Received: count=%d, [%02x %02x %02x %02x]\n", + ctxt.rx_count, exp_mac[0], exp_mac[1], exp_mac[2], exp_mac[3], + pdu->msg[5], mac[0], mac[1], mac[2], mac[3]); + return false; + } } + nas_log->info("Integrity check ok. Local: count=%d, Received: count=%d\n", + ctxt.rx_count, pdu->msg[5]); + return true; + } else { + nas_log->error("Invalid integrity check PDU size (%d)\n", pdu->N_bytes); } - nas_log->info("Integrity check ok. Local: count=%d, Received: count=%d\n", - ctxt.rx_count, pdu->msg[5]); - return true; } void nas::cipher_encrypt(byte_buffer_t *pdu) @@ -454,6 +462,17 @@ bool nas::check_cap_replay(LIBLTE_MME_UE_SECURITY_CAPABILITIES_STRUCT *caps) ******************************************************************************/ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) { + + if (!pdu) { + nas_log->error("Invalid PDU\n"); + return; + } + + if (pdu->N_bytes <= 5) { + nas_log->error("Invalid attach accept PDU size (%d)\n", pdu->N_bytes); + return; + } + LIBLTE_MME_ATTACH_ACCEPT_MSG_STRUCT attach_accept; LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT act_def_eps_bearer_context_req; LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_complete; @@ -679,6 +698,17 @@ void nas::parse_identity_request(uint32_t lcid, byte_buffer_t *pdu) { void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu) { + + if (!pdu) { + nas_log->error("Invalid PDU\n"); + return; + } + + if (pdu->N_bytes <= 5) { + nas_log->error("Invalid security mode command PDU size (%d)\n", pdu->N_bytes); + return; + } + LIBLTE_MME_SECURITY_MODE_COMMAND_MSG_STRUCT sec_mode_cmd; LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sec_mode_comp; @@ -808,6 +838,8 @@ void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *pdu) { ******************************************************************************/ void nas::send_attach_request() { + + LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req; byte_buffer_t *msg = pool_allocate; if (!msg) { @@ -861,12 +893,16 @@ void nas::send_attach_request() { (LIBLTE_BYTE_MSG_STRUCT *) msg); // Add MAC - integrity_generate(&k_nas_int[16], - ctxt.tx_count, - SECURITY_DIRECTION_UPLINK, - &msg->msg[5], - msg->N_bytes - 5, - &msg->msg[1]); + if (msg->N_bytes > 5) { + integrity_generate(&k_nas_int[16], + ctxt.tx_count, + SECURITY_DIRECTION_UPLINK, + &msg->msg[5], + msg->N_bytes - 5, + &msg->msg[1]); + } else { + nas_log->error("Invalid PDU size %d\n", msg->N_bytes); + } } else { attach_req.eps_mobile_id.type_of_id = LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI; usim->get_imsi_vec(attach_req.eps_mobile_id.imsi, 15); From 45cae1d1aba068fe4a9f3a3dc424fee6b51dc47d Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 21 Mar 2018 13:10:13 +0100 Subject: [PATCH 303/342] Fix srsENB DL TCP stalling --- srsenb/src/mac/scheduler.cc | 27 +++++++++++++++++---------- srsenb/src/mac/scheduler_metric.cc | 4 +--- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/srsenb/src/mac/scheduler.cc b/srsenb/src/mac/scheduler.cc index 51f161d4a..995363045 100644 --- a/srsenb/src/mac/scheduler.cc +++ b/srsenb/src/mac/scheduler.cc @@ -254,18 +254,22 @@ uint32_t sched::get_ul_buffer(uint16_t rnti) return ret; } +/* \Warning: This function is not mutexed because it can produce late changes on the buffer state while + * the scheduler is already allocating data, resulting in empty grants. + * Ideally we would like the scheduler to query the RLC for buffer states in order to get the most updated + * buffer state with the minimum overhead. However, the current architecture is designed to be compliant + * with the FAPI interface + */ int sched::dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) { - pthread_mutex_lock(&mutex); - int ret = 0; - if (ue_db.count(rnti)) { + int ret = 0; + if (ue_db.count(rnti)) { ue_db[rnti].dl_buffer_state(lc_id, tx_queue, retx_queue); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } - pthread_mutex_unlock(&mutex); - return ret; + return ret; } int sched::dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code) @@ -676,10 +680,11 @@ int sched::dl_sched_data(dl_sched_data_t data[MAX_DATA_LIST]) int nof_data_elems = 0; for(std::map::iterator iter=ue_db.begin(); iter!=ue_db.end(); ++iter) { - sched_ue *user = (sched_ue*) &iter->second; - uint16_t rnti = (uint16_t) iter->first; + sched_ue *user = (sched_ue*) &iter->second; + uint16_t rnti = (uint16_t) iter->first; - dl_harq_proc *h = dl_metric->get_user_allocation(user); + uint32_t data_before = user->get_pending_dl_new_data(current_tti); + dl_harq_proc *h = dl_metric->get_user_allocation(user); srslte_dci_format_t dci_format = user->get_dci_format(); data[nof_data_elems].dci_format = dci_format; @@ -706,10 +711,12 @@ int sched::dl_sched_data(dl_sched_data_t data[MAX_DATA_LIST]) Error("DCI format (%d) not implemented\n", dci_format); } if (tbs > 0) { - log_h->info("SCHED: DL %s rnti=0x%x, pid=%d, mask=0x%x, dci=%d,%d, n_rtx=%d, tbs=%d, buffer=%d, tb_en={%s,%s}\n", + log_h->info("SCHED: DL %s rnti=0x%x, pid=%d, mask=0x%x, dci=%d,%d, n_rtx=%d, tbs=%d, buffer=%d/%d, tb_en={%s,%s}\n", !is_newtx?"retx":"tx", rnti, h->get_id(), h->get_rbgmask(), data[nof_data_elems].dci_location.L, data[nof_data_elems].dci_location.ncce, h->nof_retx(0) + h->nof_retx(1), - tbs, user->get_pending_dl_new_data(current_tti), data[nof_data_elems].dci.tb_en[0]?"y":"n", + tbs, + data_before, user->get_pending_dl_new_data(current_tti), + data[nof_data_elems].dci.tb_en[0]?"y":"n", data[nof_data_elems].dci.tb_en[1]?"y":"n"); nof_data_elems++; } else { diff --git a/srsenb/src/mac/scheduler_metric.cc b/srsenb/src/mac/scheduler_metric.cc index f6fb9d9df..1d9cdb954 100644 --- a/srsenb/src/mac/scheduler_metric.cc +++ b/srsenb/src/mac/scheduler_metric.cc @@ -148,9 +148,7 @@ dl_harq_proc* dl_metric_rr::get_user_allocation(sched_ue *user) if (pending_data || (h && !h->is_empty())) { #endif if (nof_users_with_data) { - if (nof_users_with_data == 2) { - } - if ((current_tti%nof_users_with_data) != user->ue_idx) { + if ((current_tti%nof_users_with_data) != user->ue_idx) { return NULL; } } From 51e7b3fec69aa0c18b0ae59a7cc9cd77b5e82376 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 21 Mar 2018 12:14:11 +0000 Subject: [PATCH 304/342] Fixed IMSI print. --- srsepc/src/spgw/spgw.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index f54eef7df..e35a99be3 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -515,7 +515,7 @@ spgw::handle_create_session_request(struct srslte::gtpc_create_session_request * bool gtpc_present = m_imsi_to_ctr_teid.count(cs_req->imsi); if(gtpc_present) { - m_spgw_log->console("SPGW: GTP-C context for IMSI %015ul already exists.\n", cs_req->imsi); + m_spgw_log->console("SPGW: GTP-C context for IMSI %015lu already exists.\n", cs_req->imsi); delete_gtp_ctx(m_imsi_to_ctr_teid[cs_req->imsi]); m_spgw_log->console("SPGW: Deleted previous context.\n"); } From fa4d14652de0482b94b08df1f16a5a03899a124c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 21 Mar 2018 13:32:19 +0100 Subject: [PATCH 305/342] Added mutex for ue_rem/buffer access for more safety --- srsenb/hdr/mac/scheduler.h | 6 +++--- srsenb/src/mac/scheduler.cc | 24 ++++++++++++++++++------ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/srsenb/hdr/mac/scheduler.h b/srsenb/hdr/mac/scheduler.h index c3ca7d624..12c336c36 100644 --- a/srsenb/hdr/mac/scheduler.h +++ b/srsenb/hdr/mac/scheduler.h @@ -100,8 +100,8 @@ public: uint32_t get_ul_buffer(uint16_t rnti); uint32_t get_dl_buffer(uint16_t rnti); - int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue); - int dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code); + int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue); + int dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code); int dl_ant_info(uint16_t rnti, LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT *dedicated); int dl_ack_info(uint32_t tti, uint16_t rnti, uint32_t tb_idx, bool ack); @@ -217,7 +217,7 @@ private: bool configured; - pthread_mutex_t mutex; + pthread_mutex_t mutex, mutex2; }; diff --git a/srsenb/src/mac/scheduler.cc b/srsenb/src/mac/scheduler.cc index 995363045..2e0504193 100644 --- a/srsenb/src/mac/scheduler.cc +++ b/srsenb/src/mac/scheduler.cc @@ -64,6 +64,7 @@ sched::sched() : bc_aggr_level(0), rar_aggr_level(0), avail_rbg(0), P(0), start_ } pthread_mutex_init(&mutex, NULL); + pthread_mutex_init(&mutex2, NULL); reset(); } @@ -71,6 +72,7 @@ sched::~sched() { srslte_regs_free(®s); pthread_mutex_destroy(&mutex); + pthread_mutex_destroy(&mutex2); } void sched::init(rrc_interface_mac *rrc_, srslte::log* log) @@ -173,13 +175,15 @@ int sched::ue_cfg(uint16_t rnti, sched_interface::ue_cfg_t *ue_cfg) int sched::ue_rem(uint16_t rnti) { pthread_mutex_lock(&mutex); - int ret = 0; + pthread_mutex_lock(&mutex2); + int ret = 0; if (ue_db.count(rnti)) { ue_db.erase(rnti); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_mutex_unlock(&mutex2); pthread_mutex_unlock(&mutex); return ret; } @@ -217,13 +221,15 @@ int sched::bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bear int sched::bearer_ue_rem(uint16_t rnti, uint32_t lc_id) { pthread_mutex_lock(&mutex); - int ret = 0; + pthread_mutex_lock(&mutex2); + int ret = 0; if (ue_db.count(rnti)) { ue_db[rnti].rem_bearer(lc_id); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_mutex_unlock(&mutex2); pthread_mutex_unlock(&mutex); return ret; } @@ -259,9 +265,13 @@ uint32_t sched::get_ul_buffer(uint16_t rnti) * Ideally we would like the scheduler to query the RLC for buffer states in order to get the most updated * buffer state with the minimum overhead. However, the current architecture is designed to be compliant * with the FAPI interface + * + * We add a new mutex used only in ue_rem to avoid the UE being removed in between the access to + * ue_db.count() and the access to the std::map. */ int sched::dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) { + pthread_mutex_lock(&mutex2); int ret = 0; if (ue_db.count(rnti)) { ue_db[rnti].dl_buffer_state(lc_id, tx_queue, retx_queue); @@ -269,21 +279,23 @@ int sched::dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_mutex_unlock(&mutex2); return ret; } +/* \Warning Read comment in dl_rlc_buffer_state() */ int sched::dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code) { - pthread_mutex_lock(&mutex); - int ret = 0; + pthread_mutex_lock(&mutex2); + int ret = 0; if (ue_db.count(rnti)) { ue_db[rnti].mac_buffer_state(ce_code); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } - pthread_mutex_unlock(&mutex); - return ret; + pthread_mutex_unlock(&mutex2); + return ret; } int sched::dl_ant_info(uint16_t rnti, LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT *dl_ant_info) { From 62dc65556a969ff46d5027ff61b9f006a7984ab4 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 21 Mar 2018 18:45:23 +0000 Subject: [PATCH 306/342] Fixed GUTI attach procedure when authentication is successful. Ping works again. --- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 8 +++++--- srsepc/src/mme/s1ap_nas_transport.cc | 27 ++++++++++++++++++--------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 5f258ba8d..6d8da0129 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -179,7 +179,7 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, } //Send Reply to eNB - ssize_t n_sent = sctp_send(s1mme,reply_buffer->msg, reply_buffer->N_bytes, &ecm_ctx->enb_sri, 0); + ssize_t n_sent = sctp_send(s1mme,reply_buffer->msg, reply_buffer->N_bytes, &ecm_ctx->enb_sri, 0); if(n_sent == -1) { m_s1ap_log->error("Failed to send Initial Context Setup Request\n"); @@ -195,8 +195,10 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, addr.s_addr = htonl(sgw_s1u_ip); m_s1ap_log->info("Sent Intial Context Setup Request. E-RAB id %d \n",erab_ctx_req->e_RAB_ID.E_RAB_ID); m_s1ap_log->info("Initial Context -- S1-U TEID 0x%x. IP %s \n", sgw_s1u_teid,inet_ntoa(addr)); - m_s1ap_log->console("Sent Intial Context Setup Request, E-RAB id %d\n",erab_ctx_req->e_RAB_ID.E_RAB_ID); - m_s1ap_log->console("Initial Context -- S1-U TEID 0x%x. IP %s \n", sgw_s1u_teid,inet_ntoa(addr)); + m_s1ap_log->console("Initial Context Setup Request -- eNB UE S1AP Id %d, MME UE S1AP Id %d\n",in_ctxt_req->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID, in_ctxt_req->MME_UE_S1AP_ID.MME_UE_S1AP_ID); + m_s1ap_log->console("Initial Context Setup Request -- E-RAB id %d\n",erab_ctx_req->e_RAB_ID.E_RAB_ID); + m_s1ap_log->console("Initial Context Setup Request -- S1-U TEID 0x%x. IP %s \n", sgw_s1u_teid,inet_ntoa(addr)); + m_s1ap_log->console("Initial Context Setup Request -- S1-U TEID 0x%x. IP %s \n", sgw_s1u_teid,inet_ntoa(addr)); m_pool->deallocate(reply_buffer); m_pool->deallocate(nas_buffer); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 0846a0c4b..9c9180e86 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -274,8 +274,10 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA if(*reply_flag == true) { - m_s1ap_log->console("DL NAS: Sent Downlink NAs Message. DL NAS Count=%d, UL NAS count=%d\n",emm_ctx->security_ctxt.dl_nas_count,emm_ctx->security_ctxt.ul_nas_count ); + m_s1ap_log->console("DL NAS: Sent Downlink NAS Message. DL NAS Count=%d, UL NAS count=%d\n",emm_ctx->security_ctxt.dl_nas_count,emm_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",emm_ctx->security_ctxt.dl_nas_count, emm_ctx->security_ctxt.ul_nas_count); + m_s1ap_log->info("DL NAS: MME UE S1AP id %d\n",ecm_ctx->mme_ue_s1ap_id); + m_s1ap_log->console("DL NAS: MME UE S1AP id %d\n",ecm_ctx->mme_ue_s1ap_id); } m_pool->deallocate(nas_msg); return true; @@ -473,8 +475,8 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, if(it == m_s1ap->m_tmsi_to_imsi.end()) { - m_s1ap_log->console("Attach Request -- Could not find M-TMSI 0x%x", m_tmsi); - m_s1ap_log->info("Attach Request -- Could not find M-TMSI 0x%x", m_tmsi); + m_s1ap_log->console("Attach Request -- Could not find M-TMSI 0x%x\n", m_tmsi); + m_s1ap_log->info("Attach Request -- Could not find M-TMSI 0x%x\n", m_tmsi); //Could not find IMSI from M-TMSI, send Id request ue_ctx_t ue_ctx; @@ -558,8 +560,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, { ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; - m_s1ap_log->console("Found UE context. IMSI: %015lu\n",emm_ctx->imsi); - + m_s1ap_log->console("Found UE context. IMSI: %015lu, old MME UE S1AP Id %d\n",emm_ctx->imsi, ecm_ctx->mme_ue_s1ap_id); //Check NAS integrity bool msg_valid = false; emm_ctx->security_ctxt.ul_nas_count++; @@ -567,8 +568,15 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, if(msg_valid == true) { //Create new MME UE S1AP Identity - emm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + uint32_t new_mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + //Make sure context from previous MME + if(ecm_ctx->mme_ue_s1ap_id!=0) + { + m_s1ap->release_ue_ecm_ctx(ecm_ctx->mme_ue_s1ap_id); + } + emm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + ecm_ctx->mme_ue_s1ap_id = emm_ctx->mme_ue_s1ap_id; //Set EMM as de-registered emm_ctx->state = EMM_STATE_DEREGISTERED; //Save Attach type @@ -591,7 +599,8 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, ecm_ctx->erabs_ctx[i].erab_id = i; } - //m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); + //Store context based on MME UE S1AP id + m_s1ap->add_ue_ctx_to_mme_ue_s1ap_id_map(ue_ctx); //Create session request m_s1ap_log->console("GUTI Attach -- NAS Integrity OK."); m_mme_gtpc->send_create_session_request(emm_ctx->imsi); @@ -1158,8 +1167,8 @@ s1ap_nas_transport::integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_buffer_t // Check if expected mac equals the sent mac for(i=0; i<4; i++){ if(exp_mac[i] != mac[i]){ - m_s1ap_log->warning("Integrity check failure. Local: count=%d, [%02x %02x %02x %02x], " - "Received: count=%d, [%02x %02x %02x %02x]\n", + m_s1ap_log->warning("Integrity check failure. UL Local: count=%d, [%02x %02x %02x %02x], " + "Received: UL count=%d, [%02x %02x %02x %02x]\n", emm_ctx->security_ctxt.ul_nas_count, exp_mac[0], exp_mac[1], exp_mac[2], exp_mac[3], pdu->msg[5], mac[0], mac[1], mac[2], mac[3]); return false; From 3d3027f0b75017aea83ae000626142bbba131dc6 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 22 Mar 2018 14:12:48 +0000 Subject: [PATCH 307/342] Fixed GUTI attach when authentication fails. --- srsepc/src/mme/s1ap_nas_transport.cc | 56 ++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 9c9180e86..b37726e51 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -570,7 +570,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, //Create new MME UE S1AP Identity uint32_t new_mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); - //Make sure context from previous MME + //Make sure context from previous NAS connections is not present if(ecm_ctx->mme_ue_s1ap_id!=0) { m_s1ap->release_ue_ecm_ctx(ecm_ctx->mme_ue_s1ap_id); @@ -609,11 +609,61 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, } else { + emm_ctx->security_ctxt.ul_nas_count = 0; + emm_ctx->security_ctxt.dl_nas_count = 0; + + //Create new MME UE S1AP Identity + uint32_t new_mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + + //Make sure context from previous NAS connections is not present + if(ecm_ctx->mme_ue_s1ap_id!=0) + { + m_s1ap->release_ue_ecm_ctx(ecm_ctx->mme_ue_s1ap_id); + } + emm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + ecm_ctx->mme_ue_s1ap_id = emm_ctx->mme_ue_s1ap_id; + //Set EMM as de-registered + emm_ctx->state = EMM_STATE_DEREGISTERED; + //Save Attach type + emm_ctx->attach_type = attach_req.eps_attach_type; + + //Set UE ECM context + ecm_ctx->imsi = ecm_ctx->imsi; + ecm_ctx->mme_ue_s1ap_id = ecm_ctx->mme_ue_s1ap_id; + + //Set eNB information + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + memcpy(&ecm_ctx->enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + //Save whether secure ESM information transfer is necessary + ecm_ctx->eit = pdn_con_req.esm_info_transfer_flag_present; + + //Initialize E-RABs + for(uint i = 0 ; i< MAX_ERABS_PER_UE; i++) + { + ecm_ctx->erabs_ctx[i].state = ERAB_DEACTIVATED; + ecm_ctx->erabs_ctx[i].erab_id = i; + } + //Store context based on MME UE S1AP id + m_s1ap->add_ue_ctx_to_mme_ue_s1ap_id_map(ue_ctx); + //NAS integrity failed. Re-start authentication process. m_s1ap_log->console("GUTI Attach request NAS integrity failed.\n"); m_s1ap_log->console("RE-starting authentication procedure.\n"); - //pack_identity_request(); - //(srslte::byte_buffer_t *reply_msg, uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id) + uint8_t autn[16]; + uint8_t rand[16]; + //Get Authentication Vectors from HSS + if(!m_hss->gen_auth_info_answer(emm_ctx->imsi, emm_ctx->security_ctxt.k_asme, autn, rand, emm_ctx->security_ctxt.xres)) + { + m_s1ap_log->console("User not found. IMSI %015lu\n",emm_ctx->imsi); + m_s1ap_log->info("User not found. IMSI %015lu\n",emm_ctx->imsi); + return false; + } + pack_authentication_request(reply_buffer, ecm_ctx->enb_ue_s1ap_id, ecm_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"); return true; } } From 79517310d040e4303eb53923d00fc60e5bfe974e Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 22 Mar 2018 14:22:04 +0000 Subject: [PATCH 308/342] small fixes on identation --- srsepc/src/mme/s1ap_nas_transport.cc | 86 +++++++++++----------------- 1 file changed, 33 insertions(+), 53 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index b37726e51..19b1ff924 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -733,60 +733,40 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); m_s1ap->release_ue_ecm_ctx(ecm_ctx->mme_ue_s1ap_id); } - //Handle service request from Connected UE. - //Set eNB UE S1ap identity - // ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; - // m_s1ap_log->console("Service Request -- eNB UE S1AP Id %d \n", enb_ue_s1ap_id); - //m_s1ap_log->info("Service Request -- eNB UE S1AP Id %d\n ", enb_ue_s1ap_id); - - //Delete eNB context and connect. - //m_s1ap_log->console("Service Request -- User has ECM context already\n"); - //m_s1ap_log->info("Service Request -- User has ECM context already\n"); - //m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); - //int default_bearer_id = 5; - //m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, &ecm_ctx->erabs_ctx[5]); - //} - //else if(ecm_ctx->state == ECM_STATE_IDLE) - //{ - ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; - - //UE not connect. Connect normally. - m_s1ap_log->console("Service Request -- User is ECM DISCONNECTED\n"); - m_s1ap_log->info("Service Request -- User is ECM DISCONNECTED\n"); - //Create ECM context - ecm_ctx->imsi = emm_ctx->imsi; - ecm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); - emm_ctx->mme_ue_s1ap_id = ecm_ctx->mme_ue_s1ap_id; - //Set eNB information - ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; - memcpy(&ecm_ctx->enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); - - //Save whether secure ESM information transfer is necessary - ecm_ctx->eit = false; - - //Get UE IP, and uplink F-TEID - if(emm_ctx->ue_ip.s_addr == 0 ) - { - m_s1ap_log->error("UE has no valid IP assigned upon reception of service request"); - } - - m_s1ap_log->console("UE previously assigned IP: %s",inet_ntoa(emm_ctx->ue_ip)); - //Mark E-RABs as setup, but not active yet - - //Re-generate K_eNB - liblte_security_generate_k_enb(emm_ctx->security_ctxt.k_asme, emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.k_enb); - m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",emm_ctx->security_ctxt.ul_nas_count); - m_s1ap_log->console("UE Ctr TEID %d\n", emm_ctx->sgw_ctrl_fteid.teid); - - //Save UE ctx to MME UE S1AP id - m_s1ap->add_ue_ctx_to_mme_ue_s1ap_id_map(ue_ctx); - m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx,&ecm_ctx->erabs_ctx[5]); - /*} - else + + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + + //UE not connect. Connect normally. + m_s1ap_log->console("Service Request -- User is ECM DISCONNECTED\n"); + m_s1ap_log->info("Service Request -- User is ECM DISCONNECTED\n"); + //Create ECM context + ecm_ctx->imsi = emm_ctx->imsi; + ecm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + emm_ctx->mme_ue_s1ap_id = ecm_ctx->mme_ue_s1ap_id; + //Set eNB information + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + memcpy(&ecm_ctx->enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + + //Save whether secure ESM information transfer is necessary + ecm_ctx->eit = false; + + //Get UE IP, and uplink F-TEID + if(emm_ctx->ue_ip.s_addr == 0 ) { - m_s1ap_log->console("ECM context is un-initialized.\n"); - m_s1ap_log->error("ECM context is un-initialized.\n"); - }*/ + m_s1ap_log->error("UE has no valid IP assigned upon reception of service request"); + } + + m_s1ap_log->console("UE previously assigned IP: %s",inet_ntoa(emm_ctx->ue_ip)); + //Mark E-RABs as setup, but not active yet + + //Re-generate K_eNB + liblte_security_generate_k_enb(emm_ctx->security_ctxt.k_asme, emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.k_enb); + m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",emm_ctx->security_ctxt.ul_nas_count); + m_s1ap_log->console("UE Ctr TEID %d\n", emm_ctx->sgw_ctrl_fteid.teid); + + //Save UE ctx to MME UE S1AP id + m_s1ap->add_ue_ctx_to_mme_ue_s1ap_id_map(ue_ctx); + m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx,&ecm_ctx->erabs_ctx[5]); } else { From ba3a579a9211729adc51849ffe21d185d2a7e519 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 22 Mar 2018 17:04:40 +0000 Subject: [PATCH 309/342] Regenerating k_eNB on guti attach request. --- srsepc/src/mme/s1ap_nas_transport.cc | 86 ++++++---------------------- 1 file changed, 17 insertions(+), 69 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 19b1ff924..eb3fa85db 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -257,6 +257,10 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA m_s1ap_log->info("Uplink NAS: Authentication Failure\n"); handle_authentication_failure(nas_msg, ue_ctx, reply_buffer, reply_flag); break; + /* case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: + m_s1ap_log->info("Uplink NAS: Detach Request\n"); + handle_detach_request(nas_msg, ue_ctx, reply_buffer, reply_flag); + break;*/ default: m_s1ap_log->warning("Unhandled NAS integrity protected message 0x%x\n", msg_type ); m_s1ap_log->console("Unhandled NAS integrity protected message 0x%x\n", msg_type ); @@ -601,6 +605,11 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, //Store context based on MME UE S1AP id m_s1ap->add_ue_ctx_to_mme_ue_s1ap_id_map(ue_ctx); + + //Re-generate K_eNB + liblte_security_generate_k_enb(emm_ctx->security_ctxt.k_asme, emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.k_enb); + m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",emm_ctx->security_ctxt.ul_nas_count); + //Create session request m_s1ap_log->console("GUTI Attach -- NAS Integrity OK."); m_mme_gtpc->send_create_session_request(emm_ctx->imsi); @@ -972,14 +981,6 @@ s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; - //Check if EMM context already exists - //ue_ctx_t *ue_tmp_ptr = m_s1ap->find_ue_ctx_from_imsi(imsi); - //if(ue_tmp_ptr != NULL) - //{ - // m_s1ap_log->warning("Unkonw GUTI, but UE's EMM context present.\n"); - // m_s1ap->delete_ue_emm_ctx(imsi); - //} - m_s1ap_log->info("Id Response -- IMSI: %015lu\n", imsi); m_s1ap_log->console("Id Response -- IMSI: %015lu\n", imsi); @@ -1036,25 +1037,9 @@ 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->ecm_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; - /* - bool t3412_present; - bool guti_present; - bool tai_list_present; - bool eps_bearer_context_status_present; - bool lai_present; - bool ms_id_present; - bool emm_cause_present; - bool t3402_present; - bool t3423_present; - bool equivalent_plmns_present; - bool emerg_num_list_present; - bool eps_network_feature_support_present; - bool additional_update_result_present; - bool t3412_ext_present; - */ //Get decimal MCC and MNC uint32_t mcc = 0; mcc += 0x000F & m_s1ap->m_s1ap_args.mcc; @@ -1105,46 +1090,6 @@ s1ap_nas_transport::handle_tracking_area_update_request(srslte::byte_buffer_t *n tau_acc.additional_update_result_present = false; tau_acc.t3412_ext_present = false; - - //eps_update_result = LIBLTE_MME_TR - /* -typedef struct{ - LIBLTE_MME_GPRS_TIMER_STRUCT t3412; - LIBLTE_MME_EPS_MOBILE_ID_STRUCT guti; - LIBLTE_MME_TRACKING_AREA_IDENTITY_LIST_STRUCT tai_list; - LIBLTE_MME_EPS_BEARER_CONTEXT_STATUS_STRUCT eps_bearer_context_status; - LIBLTE_MME_LOCATION_AREA_ID_STRUCT lai; - LIBLTE_MME_MOBILE_ID_STRUCT ms_id; - LIBLTE_MME_GPRS_TIMER_STRUCT t3402; - LIBLTE_MME_GPRS_TIMER_STRUCT t3423; - LIBLTE_MME_PLMN_LIST_STRUCT equivalent_plmns; - LIBLTE_MME_EMERGENCY_NUMBER_LIST_STRUCT emerg_num_list; - LIBLTE_MME_EPS_NETWORK_FEATURE_SUPPORT_STRUCT eps_network_feature_support; - LIBLTE_MME_GPRS_TIMER_3_STRUCT t3412_ext; - LIBLTE_MME_ADDITIONAL_UPDATE_RESULT_ENUM additional_update_result; - uint8 eps_update_result; - uint8 emm_cause; - bool t3412_present; - bool guti_present; - bool tai_list_present; - bool eps_bearer_context_status_present; - bool lai_present; - bool ms_id_present; - bool emm_cause_present; - bool t3402_present; - bool t3423_present; - bool equivalent_plmns_present; - bool emerg_num_list_present; - bool eps_network_feature_support_present; - bool additional_update_result_present; - bool t3412_ext_present;v -}LIBLTE_MME_TRACKING_AREA_UPDATE_ACCEPT_MSG_STRUCT; - */ - - - //Send reply to eNB - //*reply_flag = true; - return true; } @@ -1256,7 +1201,6 @@ s1ap_nas_transport::handle_authentication_failure(srslte::byte_buffer_t *nas_msg m_s1ap_log->info("User not found. IMSI %015lu\n", emm_ctx->imsi); return false; } - //Pack NAS Authentication Request in Downlink NAS Transport msg pack_authentication_request(reply_msg, ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, autn, rand); @@ -1268,10 +1212,14 @@ s1ap_nas_transport::handle_authentication_failure(srslte::byte_buffer_t *nas_msg break; } - return true; - + return true; } - + /* +bool +s1ap_nas_transport::handle_detach_request(nas_msg, ue_ctx, reply_buffer, reply_flag) +{ + 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 b73a4da8f91d740007d7ba5bd0e5ff4efcde2138 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 22 Mar 2018 18:54:06 +0000 Subject: [PATCH 310/342] Starting to add support to NAS detach request. --- srsepc/hdr/mme/s1ap_nas_transport.h | 7 +++ srsepc/src/mme/s1ap_nas_transport.cc | 78 ++++++++++++++++++++++++---- 2 files changed, 74 insertions(+), 11 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index 3827ab79d..5d6a07e37 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -74,6 +74,13 @@ public: bool* reply_flag, struct sctp_sndrcvinfo *enb_sri); + bool handle_nas_detach_request(uint32_t m_tmsi, + uint32_t enb_ue_s1ap_id, + srslte::byte_buffer_t *nas_msg, + srslte::byte_buffer_t *reply_buffer, + bool* reply_flag, + struct sctp_sndrcvinfo *enb_sri); + bool handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag); bool handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); bool handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index eb3fa85db..c1e532076 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -122,6 +122,26 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA handle_nas_service_request(ntohl(*m_tmsi), enb_ue_s1ap_id, nas_msg, reply_buffer,reply_flag, enb_sri); return true; } + else if(msg_type == LIBLTE_MME_MSG_TYPE_DETACH_REQUEST) + { + m_s1ap_log->console("Received Detach Request\n"); + m_s1ap_log->info("Received Detach Request\n"); + if(!init_ue->S_TMSI_present) + { + m_s1ap_log->error("Service request -- S-TMSI not present\n"); + m_s1ap_log->console("Service request -- S-TMSI not present\n" ); + return false; + } + uint32_t *m_tmsi = (uint32_t*) &init_ue->S_TMSI.m_TMSI.buffer; + uint32_t enb_ue_s1ap_id = init_ue->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID; + m_s1ap_log->info("Detach Request -- S-TMSI 0x%x\n", ntohl(*m_tmsi)); + m_s1ap_log->console("Detach Request -- S-TMSI 0x%x\n", ntohl(*m_tmsi) ); + m_s1ap_log->info("Detach Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); + m_s1ap_log->console("Detach Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); + + handle_nas_detach_request(ntohl(*m_tmsi), enb_ue_s1ap_id, nas_msg, reply_buffer,reply_flag, enb_sri); + return true; + } else { m_s1ap_log->info("Unhandled Initial UE Message 0x%x\n",msg_type); @@ -240,27 +260,25 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA } switch (msg_type) { case LIBLTE_MME_MSG_TYPE_ATTACH_COMPLETE: - m_s1ap_log->info("Uplink NAS: Received Attach Complete\n"); - m_s1ap_log->console("Uplink NAS: Received Attach Complete\n"); + m_s1ap_log->info("Integrity Protected UL NAS: Received Attach Complete\n"); + m_s1ap_log->console("Integrity Protected UL NAS: Received Attach Complete\n"); handle_nas_attach_complete(nas_msg, ue_ctx, reply_buffer, reply_flag); break; case LIBLTE_MME_MSG_TYPE_ESM_INFORMATION_RESPONSE: - m_s1ap_log->info("Uplink NAS: Received ESM Information Response\n"); - m_s1ap_log->console("Uplink NAS: Received ESM Information Response\n"); + m_s1ap_log->info("Integrity Protected UL NAS: Received ESM Information Response\n"); + m_s1ap_log->console("Integrity Protected UL NAS: Received ESM Information Response\n"); handle_esm_information_response(nas_msg, ue_ctx, reply_buffer, reply_flag); 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("Integrity Protected UL NAS: Tracking Area Update Request\n"); + m_s1ap_log->console("Integrity Protected UL 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"); + m_s1ap_log->info("Integrity Protected UL NAS: Authentication Failure\n"); + m_s1ap_log->info("Integrity Protected UL NAS: Authentication Failure\n"); handle_authentication_failure(nas_msg, ue_ctx, reply_buffer, reply_flag); break; - /* case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: - m_s1ap_log->info("Uplink NAS: Detach Request\n"); - handle_detach_request(nas_msg, ue_ctx, reply_buffer, reply_flag); - break;*/ default: m_s1ap_log->warning("Unhandled NAS integrity protected message 0x%x\n", msg_type ); m_s1ap_log->console("Unhandled NAS integrity protected message 0x%x\n", msg_type ); @@ -557,7 +575,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, else{ m_s1ap_log->console("Attach Request -- Found M-TMSI: %d\n",m_tmsi); - m_s1ap_log->console("Attach Request -- IMSI: %d\n",it->second); + m_s1ap_log->console("Attach Request -- IMSI: %015lu\n",it->second); //Get UE EMM context ue_ctx_t *ue_ctx = m_s1ap->find_ue_ctx_from_imsi(it->second); if(ue_ctx!=NULL) @@ -569,8 +587,11 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, bool msg_valid = false; emm_ctx->security_ctxt.ul_nas_count++; msg_valid = integrity_check(emm_ctx,nas_msg); + + if(msg_valid == true) { + m_s1ap_log->console("GUTI Attach Integrity valid. UL count %d, DL count %d\n",emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.dl_nas_count); //Create new MME UE S1AP Identity uint32_t new_mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); @@ -609,6 +630,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, //Re-generate K_eNB liblte_security_generate_k_enb(emm_ctx->security_ctxt.k_asme, emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.k_enb); m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",emm_ctx->security_ctxt.ul_nas_count); + m_s1ap_log->console("Generating KeNB with UL NAS COUNT: %d\n",emm_ctx->security_ctxt.ul_nas_count); //Create session request m_s1ap_log->console("GUTI Attach -- NAS Integrity OK."); @@ -786,6 +808,39 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, return true; } +bool +s1ap_nas_transport::handle_nas_detach_request(uint32_t m_tmsi, + uint32_t enb_ue_s1ap_id, + srslte::byte_buffer_t *nas_msg, + srslte::byte_buffer_t *reply_buffer, + bool* reply_flag, + struct sctp_sndrcvinfo *enb_sri) +{ + bool mac_valid = false; + LIBLTE_MME_DETACH_REQUEST_MSG_STRUCT detach_req; + + LIBLTE_ERROR_ENUM err = liblte_mme_unpack_detach_request_msg((LIBLTE_BYTE_MSG_STRUCT*) nas_msg, &detach_req); + if(err !=LIBLTE_SUCCESS) + { + m_s1ap_log->error("Could not unpack detach request\n"); + return false; + } + + std::map::iterator it = m_s1ap->m_tmsi_to_imsi.find(m_tmsi); + if(it == m_s1ap->m_tmsi_to_imsi.end()) + { + m_s1ap_log->console("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); + m_s1ap_log->error("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); + return true; + } + ue_ctx_t *ue_ctx = m_s1ap->find_ue_ctx_from_imsi(it->second); + ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; + ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; + + m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); + emm_ctx->security_ctxt.ul_nas_count++; + return true; +} bool s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag) { @@ -882,6 +937,7 @@ s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas return true; } + bool s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) { From d82c0b7f6b1a66251f4b09e115a9b71c99c6d287 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 22 Mar 2018 22:42:31 +0000 Subject: [PATCH 311/342] Adding handling of detach request. --- srsepc/hdr/mme/s1ap_nas_transport.h | 2 +- srsepc/src/mme/s1ap_nas_transport.cc | 67 ++++++++++++++++++++-------- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index 5d6a07e37..9f5b1b646 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -87,8 +87,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_buffer, bool *reply_flag); + bool handle_nas_detach_request(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag); bool integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_buffer_t *pdu); bool short_integrity_check(ue_emm_ctx_t *emm_ctx, srslte::byte_buffer_t *pdu); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index c1e532076..6e8c3730f 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -124,8 +124,8 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA } else if(msg_type == LIBLTE_MME_MSG_TYPE_DETACH_REQUEST) { - m_s1ap_log->console("Received Detach Request\n"); - m_s1ap_log->info("Received Detach Request\n"); + m_s1ap_log->console("Received Initial UE message -- Detach Request\n"); + m_s1ap_log->info("Received Initial UE message -- Detach Request\n"); if(!init_ue->S_TMSI_present) { m_s1ap_log->error("Service request -- S-TMSI not present\n"); @@ -276,7 +276,12 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA break; case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_FAILURE: m_s1ap_log->info("Integrity Protected UL NAS: Authentication Failure\n"); - m_s1ap_log->info("Integrity Protected UL NAS: Authentication Failure\n"); + m_s1ap_log->console("Integrity Protected UL NAS: Authentication Failure\n"); + handle_authentication_failure(nas_msg, ue_ctx, reply_buffer, reply_flag); + break; + case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: + m_s1ap_log->info("Integrity Protected UL NAS: Detach Request\n"); + m_s1ap_log->console("Integrity Protected UL NAS: Detach Request\n"); handle_authentication_failure(nas_msg, ue_ctx, reply_buffer, reply_flag); break; default: @@ -582,35 +587,31 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, { ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; - m_s1ap_log->console("Found UE context. IMSI: %015lu, old MME UE S1AP Id %d\n",emm_ctx->imsi, ecm_ctx->mme_ue_s1ap_id); + m_s1ap_log->console("Found UE context. IMSI: %015lu, old eNB UE S1ap Id %d, old MME UE S1AP Id %d\n",emm_ctx->imsi, ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id); //Check NAS integrity bool msg_valid = false; emm_ctx->security_ctxt.ul_nas_count++; msg_valid = integrity_check(emm_ctx,nas_msg); - if(msg_valid == true) { m_s1ap_log->console("GUTI Attach Integrity valid. UL count %d, DL count %d\n",emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.dl_nas_count); - //Create new MME UE S1AP Identity - uint32_t new_mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); - - //Make sure context from previous NAS connections is not present - if(ecm_ctx->mme_ue_s1ap_id!=0) + if(emm_ctx->state != EMM_STATE_DEREGISTERED) { - m_s1ap->release_ue_ecm_ctx(ecm_ctx->mme_ue_s1ap_id); + m_s1ap_log->error("Received Attach Request from attached user.\n"); + m_s1ap_log->console("Received Attach Request from attached user.\n"); + //FIXME handle error case + return false; } + //Create new MME UE S1AP Identity emm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); ecm_ctx->mme_ue_s1ap_id = emm_ctx->mme_ue_s1ap_id; - //Set EMM as de-registered - emm_ctx->state = EMM_STATE_DEREGISTERED; + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + ecm_ctx->imsi = ecm_ctx->imsi; + //Save Attach type emm_ctx->attach_type = attach_req.eps_attach_type; - //Set UE ECM context - ecm_ctx->imsi = ecm_ctx->imsi; - ecm_ctx->mme_ue_s1ap_id = ecm_ctx->mme_ue_s1ap_id; - //Set eNB information ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; memcpy(&ecm_ctx->enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); @@ -788,7 +789,6 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, } m_s1ap_log->console("UE previously assigned IP: %s",inet_ntoa(emm_ctx->ue_ip)); - //Mark E-RABs as setup, but not active yet //Re-generate K_eNB liblte_security_generate_k_enb(emm_ctx->security_ctxt.k_asme, emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.k_enb); @@ -837,10 +837,39 @@ s1ap_nas_transport::handle_nas_detach_request(uint32_t m_tmsi, ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; - m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); + m_mme_gtpc->send_delete_session_request(emm_ctx->imsi); + emm_ctx->state = EMM_STATE_DEREGISTERED; emm_ctx->security_ctxt.ul_nas_count++; + + m_s1ap_log->console("Received. M-TMSI 0x%x\n", m_tmsi); + //Received detach request as an initial UE message + //No need to clear ECM context; the request would have been sent as Uplink NAS transport if it was present. return true; } + +//FIXME re-factor to reduce code duplication +bool +s1ap_nas_transport::handle_nas_detach_request(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) +{ + + m_s1ap_log->console("Detach request -- IMSI %015lu", ue_ctx->emm_ctx.imsi); + m_s1ap_log->info("Detach request -- IMSI %015lu", ue_ctx->emm_ctx.imsi); + LIBLTE_MME_DETACH_REQUEST_MSG_STRUCT detach_req; + + LIBLTE_ERROR_ENUM err = liblte_mme_unpack_detach_request_msg((LIBLTE_BYTE_MSG_STRUCT*) nas_msg, &detach_req); + if(err !=LIBLTE_SUCCESS) + { + m_s1ap_log->error("Could not unpack detach request\n"); + return false; + } + + if(ue_ctx->ecm_ctx.mme_ue_s1ap_id!=0) + { + m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(&ue_ctx->ecm_ctx, reply_msg); + } + return true; +} + bool s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag) { From 3bc2cb859c48789c31daa7ed6e1accfd7c8882fc Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 23 Mar 2018 16:50:41 +0000 Subject: [PATCH 312/342] Sending ESM information request when GUTI attach passes integrity checks. --- srsepc/src/mme/s1ap.cc | 4 +-- srsepc/src/mme/s1ap_ctx_mngmt_proc.cc | 8 ++++-- srsepc/src/mme/s1ap_nas_transport.cc | 41 +++++++++++++++++++++++---- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 4bb71367b..c22870243 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -550,10 +550,10 @@ s1ap::activate_eps_bearer(uint64_t imsi, uint8_t ebi) uint32_t s1ap::allocate_m_tmsi(uint64_t imsi) { - uint32_t m_tmsi = m_next_m_tmsi++; + // uint32_t m_tmsi = m_next_m_tmsi++; + uint32_t m_tmsi = m_next_m_tmsi; m_tmsi_to_imsi.insert(std::pair(m_tmsi,imsi)); m_s1ap_log->debug("Allocated M-TMSI 0x%x to IMSI %015lu,\n",m_tmsi,imsi); - //uint32_t m_tmsi = 0x0123; return m_tmsi; } diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 6d8da0129..2938b128c 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -285,9 +285,13 @@ s1ap_ctx_mngmt_proc::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECON //There are active E-RABs, send release access mearers request m_s1ap_log->console("There are active E-RABs, send release access mearers request"); m_s1ap_log->info("There are active E-RABs, send release access mearers request"); - m_mme_gtpc->send_release_access_bearers_request(ecm_ctx->imsi); - //The handle_releease_access_bearers_response function will make sure to mark E-RABS DEACTIVATED + + //The handle_release_access_bearers_response function will make sure to mark E-RABS DEACTIVATED //It will release the UEs downstream S1-u and keep the upstream S1-U connection active. + m_mme_gtpc->send_release_access_bearers_request(ecm_ctx->imsi); + + //Send release context command to enb, so that it can release it's bearers + send_ue_context_release_command(ecm_ctx,reply_buffer); } else { diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 6e8c3730f..5e40cf219 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -592,7 +592,6 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, bool msg_valid = false; emm_ctx->security_ctxt.ul_nas_count++; msg_valid = integrity_check(emm_ctx,nas_msg); - if(msg_valid == true) { m_s1ap_log->console("GUTI Attach Integrity valid. UL count %d, DL count %d\n",emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.dl_nas_count); @@ -609,6 +608,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; ecm_ctx->imsi = ecm_ctx->imsi; + emm_ctx->procedure_transaction_id = pdn_con_req.proc_transaction_id; //Save Attach type emm_ctx->attach_type = attach_req.eps_attach_type; @@ -627,16 +627,40 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, //Store context based on MME UE S1AP id m_s1ap->add_ue_ctx_to_mme_ue_s1ap_id_map(ue_ctx); - + //Re-generate K_eNB liblte_security_generate_k_enb(emm_ctx->security_ctxt.k_asme, emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.k_enb); m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",emm_ctx->security_ctxt.ul_nas_count); m_s1ap_log->console("Generating KeNB with UL NAS COUNT: %d\n",emm_ctx->security_ctxt.ul_nas_count); + + m_s1ap_log->console("Attach request -- IMSI: %015lu\n", ecm_ctx->imsi); + m_s1ap_log->info("Attach request -- IMSI: %015lu\n", ecm_ctx->imsi); + m_s1ap_log->console("Attach request -- eNB-UE S1AP Id: %d, MME-UE S1AP Id: %d\n", ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id); + m_s1ap_log->console("Attach Request -- UE Network Capabilities EEA: %d%d%d%d%d%d%d%d\n", + attach_req.ue_network_cap.eea[0], attach_req.ue_network_cap.eea[1], attach_req.ue_network_cap.eea[2], attach_req.ue_network_cap.eea[3], + attach_req.ue_network_cap.eea[4], attach_req.ue_network_cap.eea[5], attach_req.ue_network_cap.eea[6], attach_req.ue_network_cap.eea[7]); + m_s1ap_log->console("Attach Request -- UE Network Capabilities EIA: %d%d%d%d%d%d%d%d\n", + attach_req.ue_network_cap.eia[0], attach_req.ue_network_cap.eia[1], attach_req.ue_network_cap.eia[2], attach_req.ue_network_cap.eia[3], + attach_req.ue_network_cap.eia[4], attach_req.ue_network_cap.eia[5], attach_req.ue_network_cap.eia[6], attach_req.ue_network_cap.eia[7]); + m_s1ap_log->console("Attach Request -- MS Network Capabilities Present: %s\n", attach_req.ms_network_cap_present ? "true" : "false"); + m_s1ap_log->console("PDN Connectivity Request -- EPS Bearer Identity requested: %d\n", pdn_con_req.eps_bearer_id); + m_s1ap_log->console("PDN Connectivity Request -- Procedure Transaction Id: %d\n", pdn_con_req.proc_transaction_id); + m_s1ap_log->console("PDN Connectivity Request -- ESM Information Transfer requested: %s\n", pdn_con_req.esm_info_transfer_flag_present ? "true" : "false"); //Create session request - m_s1ap_log->console("GUTI Attach -- NAS Integrity OK."); - m_mme_gtpc->send_create_session_request(emm_ctx->imsi); - *reply_flag = false; //No reply needed + m_s1ap_log->console("GUTI Attach -- NAS Integrity OK.\n"); + if(ecm_ctx->eit) + { + m_s1ap_log->console("Secure ESM information transfer requested.\n"); + m_s1ap_log->info("Secure ESM information transfer requested.\n"); + pack_esm_information_request(reply_buffer, emm_ctx, ecm_ctx); + *reply_flag = true; + } + else + { + m_mme_gtpc->send_create_session_request(emm_ctx->imsi); + *reply_flag = false; //No reply needed + } return true; } else @@ -843,7 +867,10 @@ s1ap_nas_transport::handle_nas_detach_request(uint32_t m_tmsi, m_s1ap_log->console("Received. M-TMSI 0x%x\n", m_tmsi); //Received detach request as an initial UE message - //No need to clear ECM context; the request would have been sent as Uplink NAS transport if it was present. + //eNB created new ECM context to send the detach request; this needs to be cleared. + ecm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx, reply_buffer); return true; } @@ -863,6 +890,8 @@ s1ap_nas_transport::handle_nas_detach_request(srslte::byte_buffer_t *nas_msg, ue return false; } + m_mme_gtpc->send_delete_session_request(ue_ctx->emm_ctx.imsi); + ue_ctx->emm_ctx.state = EMM_STATE_DEREGISTERED; if(ue_ctx->ecm_ctx.mme_ue_s1ap_id!=0) { m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(&ue_ctx->ecm_ctx, reply_msg); From 45a1e8425b98e663c5b6f76e0eeede5c11e62d02 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 23 Mar 2018 17:15:27 +0000 Subject: [PATCH 313/342] Fix bug in dettach request from UL Nas transport --- srsepc/src/mme/s1ap_nas_transport.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 5e40cf219..d497ca30f 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -282,7 +282,7 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: m_s1ap_log->info("Integrity Protected UL NAS: Detach Request\n"); m_s1ap_log->console("Integrity Protected UL NAS: Detach Request\n"); - handle_authentication_failure(nas_msg, ue_ctx, reply_buffer, reply_flag); + handle_nas_detach_request(nas_msg, ue_ctx, reply_buffer, reply_flag); break; default: m_s1ap_log->warning("Unhandled NAS integrity protected message 0x%x\n", msg_type ); @@ -894,7 +894,7 @@ s1ap_nas_transport::handle_nas_detach_request(srslte::byte_buffer_t *nas_msg, ue ue_ctx->emm_ctx.state = EMM_STATE_DEREGISTERED; if(ue_ctx->ecm_ctx.mme_ue_s1ap_id!=0) { - m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(&ue_ctx->ecm_ctx, reply_msg); + m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(&ue_ctx->ecm_ctx, reply_msg); } return true; } From fb1e87cf53b5f332c1fc1cc2f5a0fefdbfdcb015 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Sat, 24 Mar 2018 14:59:22 +0000 Subject: [PATCH 314/342] Fixing bug for IMSI attach of already attached user. --- srsepc/src/mme/s1ap_nas_transport.cc | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index d497ca30f..34fc3e436 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -374,10 +374,27 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, ue_ecm_ctx_t *ecm_ctx = &ue_ctx.ecm_ctx; //Set UE's EMM context - emm_ctx->imsi = 0; + uint64_t imsi = 0; for(int i=0;i<=14;i++){ - emm_ctx->imsi += attach_req.eps_mobile_id.imsi[i]*std::pow(10,14-i); + imsi += attach_req.eps_mobile_id.imsi[i]*std::pow(10,14-i); } + + //Check if UE is + ue_ctx_t *old_ctx = m_s1ap->find_ue_ctx_from_imsi(imsi); + if(old_ctx!=NULL) + { + m_s1ap_log->console("Attach Request -- UE is already attached."); + m_s1ap_log->info("Attach Request -- UE is already attached."); + //Detaching previoulsy attached UE. + m_mme_gtpc->send_delete_session_request(imsi); + if(old_ctx->ecm_ctx.mme_ue_s1ap_id!=0) + { + m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(&old_ctx->ecm_ctx, reply_buffer); + } + m_s1ap->delete_ue_ctx(imsi); + } + + emm_ctx->imsi = imsi; emm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); emm_ctx->state = EMM_STATE_DEREGISTERED; //Save UE network capabilities From ea8e7c9301800f3b2bcc173488bc91eda96a895d Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Sat, 24 Mar 2018 16:31:29 +0000 Subject: [PATCH 315/342] Fixed bug in GUTI attach when UE is already attached. --- srsepc/src/mme/s1ap_nas_transport.cc | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 34fc3e436..881d1b386 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -609,16 +609,10 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, bool msg_valid = false; emm_ctx->security_ctxt.ul_nas_count++; msg_valid = integrity_check(emm_ctx,nas_msg); - if(msg_valid == true) + if(msg_valid == true && emm_ctx->state == EMM_STATE_DEREGISTERED) { m_s1ap_log->console("GUTI Attach Integrity valid. UL count %d, DL count %d\n",emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.dl_nas_count); - if(emm_ctx->state != EMM_STATE_DEREGISTERED) - { - m_s1ap_log->error("Received Attach Request from attached user.\n"); - m_s1ap_log->console("Received Attach Request from attached user.\n"); - //FIXME handle error case - return false; - } + //Create new MME UE S1AP Identity emm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); ecm_ctx->mme_ue_s1ap_id = emm_ctx->mme_ue_s1ap_id; @@ -682,6 +676,19 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, } else { + if(emm_ctx->state != EMM_STATE_DEREGISTERED) + { + m_s1ap_log->error("Received GUTI-Attach Request from attached user.\n"); + m_s1ap_log->console("Received GUTI-Attach Request from attached user.\n"); + + //Delete previous Ctx, restart authentication + //Detaching previoulsy attached UE. + m_mme_gtpc->send_delete_session_request(emm_ctx->imsi); + if(ecm_ctx->mme_ue_s1ap_id!=0) + { + m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx, reply_buffer); + } + } emm_ctx->security_ctxt.ul_nas_count = 0; emm_ctx->security_ctxt.dl_nas_count = 0; From cb0f7fc8c2574c222a3ca3938df5c60ba782d523 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Sat, 24 Mar 2018 16:36:13 +0000 Subject: [PATCH 316/342] Changed print when service request integrity fails. --- srsepc/src/mme/s1ap_nas_transport.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 881d1b386..2d11384ae 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -849,9 +849,8 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, } else { - m_s1ap_log->console("Service Request -- Short MAC invalid. Re-starting authentication procedure \n"); - m_s1ap_log->console("Service Request -- Short MAC invalid. Re-starting authentication procedure \n"); - m_s1ap_log->console("Authentication procedure is not restarted yet!\n"); + m_s1ap_log->console("Service Request -- Short MAC invalid. Ignoring service request\n"); + m_s1ap_log->console("Service Request -- Short MAC invalid. Ignoring service request\n"); } return true; } From ff103dc4cda0db0ed110e8e1f24513d0e3360423 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 26 Mar 2018 11:01:28 +0100 Subject: [PATCH 317/342] Remove debig prints --- srsepc/src/spgw/spgw.cc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index e35a99be3..191e131df 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -387,15 +387,6 @@ spgw::handle_sgi_pdu(srslte::byte_buffer_t *msg) { m_spgw_log->error("Mis-match between packet bytes and sent bytes: Sent: %d, Packet: %d \n",n,msg->N_bytes); } - - gettimeofday(&t_now, NULL); - t_delta.tv_sec = t_now.tv_sec - m_t_last_dl.tv_sec; - t_delta.tv_usec = t_now.tv_sec - m_t_last_dl.tv_usec; - if(t_delta.tv_sec>=5) - { - m_t_last_dl = t_now; - m_spgw_log->console("Sent %d bytes DL over the last %d.%d seconds. Bitrate = \n",msg->N_bytes, t_delta.tv_sec, t_delta.tv_usec/1000); - } return; } From 57220bd6a8bb52d6f3ecbb6c9f03dcbb158ff64f Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 26 Mar 2018 11:25:13 +0100 Subject: [PATCH 318/342] Fixed compiler warnings. --- lib/src/asn1/liblte_mme.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/asn1/liblte_mme.cc b/lib/src/asn1/liblte_mme.cc index da79fb791..6d9dedcdc 100644 --- a/lib/src/asn1/liblte_mme.cc +++ b/lib/src/asn1/liblte_mme.cc @@ -296,10 +296,10 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_mobile_id_ie(LIBLTE_MME_MOBILE_ID_STRUCT *mob uint8 **ie_ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *id; - uint32 id32; + uint8 *id = NULL; + uint32 id32 = 0; uint32 i; - uint8 length; + uint8 length = 0; bool odd = false; if(mobile_id != NULL && From b1f4ee47d1bbb9b1e05a3923e879470521073fed Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 26 Mar 2018 11:58:35 +0100 Subject: [PATCH 319/342] Temporally removed unhandled UE cap info. --- srsepc/hdr/mme/s1ap.h | 2 - srsepc/hdr/mme/s1ap_ue_cap_info.h | 58 ---------------------- srsepc/src/mme/s1ap.cc | 10 +--- srsepc/src/mme/s1ap_ue_cap_info.cc | 78 ------------------------------ 4 files changed, 1 insertion(+), 147 deletions(-) delete mode 100644 srsepc/hdr/mme/s1ap_ue_cap_info.h delete mode 100644 srsepc/src/mme/s1ap_ue_cap_info.cc diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index d417d9442..31ea68436 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -44,7 +44,6 @@ #include "mme/s1ap_mngmt_proc.h" #include "mme/s1ap_nas_transport.h" #include "mme/s1ap_ctx_mngmt_proc.h" -#include "mme/s1ap_ue_cap_info.h" #include "mme/mme_gtpc.h" #include "hss/hss.h" @@ -112,7 +111,6 @@ public: s1ap_mngmt_proc* m_s1ap_mngmt_proc; s1ap_nas_transport* m_s1ap_nas_transport; s1ap_ctx_mngmt_proc* m_s1ap_ctx_mngmt_proc; - s1ap_ue_cap_info* m_s1ap_ue_cap_info; std::map m_tmsi_to_imsi; diff --git a/srsepc/hdr/mme/s1ap_ue_cap_info.h b/srsepc/hdr/mme/s1ap_ue_cap_info.h deleted file mode 100644 index 4e3b4c14e..000000000 --- a/srsepc/hdr/mme/s1ap_ue_cap_info.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2017 Software Radio Systems Limited - * - * \section LICENSE - * - * This file is part of srsLTE. - * - * srsLTE 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. - * - * srsLTE 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/. - * - */ -#ifndef S1AP_UE_CAP_INFO_H -#define S1AP_UE_CAP_INFO_H - -#include "srslte/asn1/liblte_s1ap.h" -#include "srslte/common/common.h" -#include "mme/s1ap_common.h" -#include "srslte/common/log_filter.h" - -namespace srsepc{ - -class s1ap; - -class s1ap_ue_cap_info -{ -public: - - static s1ap_ue_cap_info *m_instance; - - static s1ap_ue_cap_info* get_instance(void); - static void cleanup(void); - void init(void); - - bool handle_ue_capability_info_indication(LIBLTE_S1AP_MESSAGE_UECAPABILITYINFOINDICATION_STRUCT *msg, sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); - -private: - s1ap_ue_cap_info(); - virtual ~s1ap_ue_cap_info(); - - s1ap* m_s1ap; - srslte::log_filter *m_s1ap_log; -}; -} //namespace srsepc -#endif diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index c22870243..3fe34806c 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -92,9 +92,6 @@ s1ap::init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log, hss_interface_s1 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(); - m_s1ap_ue_cap_info = s1ap_ue_cap_info::get_instance(); //UE Capability Information - m_s1ap_ue_cap_info->init(); - //Get pointer to GTP-C class m_mme_gtpc = mme_gtpc::get_instance(); @@ -132,7 +129,6 @@ s1ap::stop() s1ap_mngmt_proc::cleanup(); s1ap_nas_transport::cleanup(); s1ap_ctx_mngmt_proc::cleanup(); - s1ap_ue_cap_info::cleanup(); return; } @@ -142,7 +138,7 @@ s1ap::get_s1_mme() return m_s1mme; } -uint32_t +uint32_t s1ap::get_next_mme_ue_s1ap_id() { return m_next_mme_ue_s1ap_id++; @@ -256,10 +252,6 @@ s1ap::handle_initiating_message(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg, stru m_s1ap_log->info("Received UE Context Release Request Message.\n"); m_s1ap_ctx_mngmt_proc->handle_ue_context_release_request(&msg->choice.UEContextReleaseRequest, enb_sri, reply_buffer, &reply_flag); break; - case LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECAPABILITYINFOINDICATION: - m_s1ap_log->info("Received UE Context Release Request Message.\n"); - m_s1ap_ue_cap_info->handle_ue_capability_info_indication(&msg->choice.UECapabilityInfoIndication, enb_sri, reply_buffer, &reply_flag); - break; default: m_s1ap_log->error("Unhandled S1AP intiating message: %s\n", liblte_s1ap_initiatingmessage_choice_text[msg->choice_type]); m_s1ap_log->console("Unhandled S1APintiating message: %s\n", liblte_s1ap_initiatingmessage_choice_text[msg->choice_type]); diff --git a/srsepc/src/mme/s1ap_ue_cap_info.cc b/srsepc/src/mme/s1ap_ue_cap_info.cc deleted file mode 100644 index f06fde165..000000000 --- a/srsepc/src/mme/s1ap_ue_cap_info.cc +++ /dev/null @@ -1,78 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2017 Software Radio Systems Limited - * - * \section LICENSE - * - * This file is part of srsLTE. - * - * srsLTE 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. - * - * srsLTE 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 "mme/s1ap.h" -#include "mme/s1ap_ue_cap_info.h" - -namespace srsepc{ - -s1ap_ue_cap_info* s1ap_ue_cap_info::m_instance = NULL; -boost::mutex s1ap_ue_cap_info_instance_mutex; - - -s1ap_ue_cap_info::s1ap_ue_cap_info() -{ -} - -s1ap_ue_cap_info::~s1ap_ue_cap_info() -{ -} - -s1ap_ue_cap_info* -s1ap_ue_cap_info::get_instance(void) -{ - boost::mutex::scoped_lock lock(s1ap_ue_cap_info_instance_mutex); - if(NULL == m_instance) { - m_instance = new s1ap_ue_cap_info(); - } - return(m_instance); -} - -void -s1ap_ue_cap_info::cleanup(void) -{ - boost::mutex::scoped_lock lock(s1ap_ue_cap_info_instance_mutex); - if(NULL != m_instance) { - delete m_instance; - m_instance = NULL; - } -} - -void -s1ap_ue_cap_info::init(void) -{ - m_s1ap = s1ap::get_instance(); - m_s1ap_log = m_s1ap->m_s1ap_log; -} - -bool -s1ap_ue_cap_info::handle_ue_capability_info_indication(LIBLTE_S1AP_MESSAGE_UECAPABILITYINFOINDICATION_STRUCT *msg, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag) -{ - m_s1ap_log->info("UE Capability Info Indication\n"); - m_s1ap_log->console("UE Capability Info Indication\n"); - return true; -} - -} //namespace srsepc From 0435e996f377fd7348d8ef49cd15832af43649bb Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 26 Mar 2018 13:09:48 +0200 Subject: [PATCH 320/342] print PUSCH payload as hex --- srsue/src/phy/phch_worker.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index cb27a5000..47fdb9591 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -1108,7 +1108,8 @@ void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint8_t *payload, ui srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, SRSLTE_CQI_STR_MAX_CHAR); uint8_t dummy[2] = {0,0}; - log_h->info("PUSCH: tti_tx=%d, alloc=(%d,%d), tbs=%d, mcs=%d, rv=%d%s%s%s, cfo=%.1f KHz%s%s%s\n", + log_h->info_hex(payload, grant->mcs.tbs/8, + "PUSCH: tti_tx=%d, alloc=(%d,%d), tbs=%d, mcs=%d, rv=%d%s%s%s, cfo=%.1f KHz%s%s%s\n", (tti + HARQ_DELAY_MS) % 10240, grant->n_prb[0], grant->n_prb[0] + grant->L_prb, grant->mcs.tbs / 8, grant->mcs.idx, rv, From 4ad02545b3a77f85268f67b123f854db633685e0 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 26 Mar 2018 13:10:38 +0200 Subject: [PATCH 321/342] fix printing issue in UM --- lib/src/upper/rlc_um.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 6bbefaf78..6bad2a2cb 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -173,7 +173,7 @@ uint32_t rlc_um::get_bearer() void rlc_um::write_sdu(byte_buffer_t *sdu) { tx_sdu_queue.write(sdu); - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (% B ,tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B ,tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); } /**************************************************************************** From 902feeda285320454e13533590417aeb34415518 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 26 Mar 2018 13:13:47 +0200 Subject: [PATCH 322/342] fix printf in s1ap --- srsepc/src/mme/s1ap_nas_transport.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 5f791caa5..4cd29703b 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -118,12 +118,12 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA } else if(msg_type == LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST) { - m_s1ap_log->info("Received Service Request \n"); - m_s1ap_log->console("Received Service Request \n"); + m_s1ap_log->info("Received Service Request\n"); + m_s1ap_log->console("Received Service Request\n"); liblte_mme_unpack_service_request_msg((LIBLTE_BYTE_MSG_STRUCT*) nas_msg, &service_req); - m_s1ap_log->info("Service Request not implemented. Sending Service Reject."); - m_s1ap_log->console("Service Request not implemented. Sending Service Reject."); + m_s1ap_log->info("Service Request not implemented. Sending Service Reject.\n"); + m_s1ap_log->console("Service Request not implemented. Sending Service Reject.\n"); /* Force UE to re-attach */ pack_service_reject(reply_buffer, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED, enb_ue_s1ap_id); *reply_flag = true; From e5534d601781cd51c10cd71cdbeb688ee397733c Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 26 Mar 2018 21:11:39 +0200 Subject: [PATCH 323/342] Remove leftovers from merge --- srsepc/epc.conf.example | 3 --- 1 file changed, 3 deletions(-) diff --git a/srsepc/epc.conf.example b/srsepc/epc.conf.example index 767c0620c..7fabca584 100644 --- a/srsepc/epc.conf.example +++ b/srsepc/epc.conf.example @@ -10,12 +10,9 @@ # tac: 16-bit Tracking Area Code. # mcc: Mobile Country Code # mnc: Mobile Network Code -<<<<<<< HEAD # mme_bindx_addr: IP subnet to listen for eNB S1 connnections # apn: Set Access Point Name (APN) -======= # mme_bind_addr: IP bind addr to listen for eNB S1 connnections ->>>>>>> epc # ##################################################################### [mme] From 0ac766658a6973e3500fd894da2a7b4d5f32f7d9 Mon Sep 17 00:00:00 2001 From: Eric Schreiber Date: Mon, 26 Mar 2018 17:21:07 -0400 Subject: [PATCH 324/342] Initialize the E_RABFailedToSetupListCtxtSURes_present and CriticalityDiagnostics_present members of the LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT to false to prevent "[S1AP] [E] Failed to send InitialContextSetupResponse" errors. When these members are set to false the liblte_s1ap_pack_initialcontextsetupresponse routine ignores the corresponding (uninitialized) structures when serializing the response pdu. --- srsenb/src/upper/rrc.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/srsenb/src/upper/rrc.cc b/srsenb/src/upper/rrc.cc index f1ae51016..e025dfca4 100644 --- a/srsenb/src/upper/rrc.cc +++ b/srsenb/src/upper/rrc.cc @@ -1069,6 +1069,9 @@ void rrc::ue::notify_s1ap_ue_ctxt_setup_complete() { LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT res; res.ext = false; + res.E_RABFailedToSetupListCtxtSURes_present = false; + res.CriticalityDiagnostics_present = false; + res.E_RABSetupListCtxtSURes.len = 0; res.E_RABFailedToSetupListCtxtSURes.len = 0; From 49a830e5481a61d154270365dbd9f4879a7f8a0e Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 28 Mar 2018 11:02:41 +0100 Subject: [PATCH 325/342] Making sure TAU requests are counted. --- srsepc/hdr/mme/s1ap_nas_transport.h | 7 ++++ srsepc/src/mme/s1ap_nas_transport.cc | 49 ++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index 9f5b1b646..500f41565 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -81,6 +81,13 @@ public: bool* reply_flag, struct sctp_sndrcvinfo *enb_sri); + bool handle_nas_tracking_area_update_request( uint32_t m_tmsi, + uint32_t enb_ue_s1ap_id, + srslte::byte_buffer_t *nas_msg, + srslte::byte_buffer_t *reply_buffer, + bool* reply_flag, + struct sctp_sndrcvinfo *enb_sri); + bool handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag); bool handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); bool handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 2d11384ae..eb64a09eb 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -128,8 +128,8 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA m_s1ap_log->info("Received Initial UE message -- Detach Request\n"); if(!init_ue->S_TMSI_present) { - m_s1ap_log->error("Service request -- S-TMSI not present\n"); - m_s1ap_log->console("Service request -- S-TMSI not present\n" ); + m_s1ap_log->error("Detach request -- S-TMSI not present\n"); + m_s1ap_log->console("Detach request -- S-TMSI not present\n" ); return false; } uint32_t *m_tmsi = (uint32_t*) &init_ue->S_TMSI.m_TMSI.buffer; @@ -142,6 +142,26 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA handle_nas_detach_request(ntohl(*m_tmsi), enb_ue_s1ap_id, nas_msg, reply_buffer,reply_flag, enb_sri); return true; } + else if(msg_type == LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REQUEST) + { + m_s1ap_log->console("Received Initial UE message -- Tracking Area Update Request\n"); + m_s1ap_log->info("Received Initial UE message -- Tracking Area Update Request\n"); + if(!init_ue->S_TMSI_present) + { + m_s1ap_log->error("Tracking Area Update Request -- S-TMSI not present\n"); + m_s1ap_log->console("Tracking Area Update Request -- S-TMSI not present\n" ); + return false; + } + uint32_t *m_tmsi = (uint32_t*) &init_ue->S_TMSI.m_TMSI.buffer; + uint32_t enb_ue_s1ap_id = init_ue->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID; + m_s1ap_log->info("Tracking Area Update Request -- S-TMSI 0x%x\n", ntohl(*m_tmsi)); + m_s1ap_log->console("Tracking Area Update Request -- S-TMSI 0x%x\n", ntohl(*m_tmsi) ); + m_s1ap_log->info("Tracking Area Update Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); + m_s1ap_log->console("Tracking Area Update Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); + + handle_nas_tracking_area_update_request(ntohl(*m_tmsi), enb_ue_s1ap_id, nas_msg, reply_buffer,reply_flag, enb_sri); + return true; + } else { m_s1ap_log->info("Unhandled Initial UE Message 0x%x\n",msg_type); @@ -922,6 +942,31 @@ s1ap_nas_transport::handle_nas_detach_request(srslte::byte_buffer_t *nas_msg, ue return true; } +bool +s1ap_nas_transport::handle_nas_tracking_area_update_request(uint32_t m_tmsi, + uint32_t enb_ue_s1ap_id, + srslte::byte_buffer_t *nas_msg, + srslte::byte_buffer_t *reply_buffer, + bool* reply_flag, + struct sctp_sndrcvinfo *enb_sri) +{ + m_s1ap_log->console("Warning: Tracking area update requests are not handled yet.\n"); + m_s1ap_log->warning("Tracking area update requests are not handled yet.\n"); + + std::map::iterator it = m_s1ap->m_tmsi_to_imsi.find(m_tmsi); + if(it == m_s1ap->m_tmsi_to_imsi.end()) + { + m_s1ap_log->console("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); + m_s1ap_log->error("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); + return true; + } + ue_ctx_t *ue_ctx = m_s1ap->find_ue_ctx_from_imsi(it->second); + ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; + ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; + + emm_ctx->security_ctxt.ul_nas_count++;//Increment the NAS count, not to break the security ctx + return true; +} bool s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_buffer, bool* reply_flag) { From 09ac36a618eeaed51581a622e00e633e17a626ba Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 28 Mar 2018 12:01:15 +0100 Subject: [PATCH 326/342] Making sure DNS address is present in the epc.conf --- srsepc/epc.conf.example | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/srsepc/epc.conf.example b/srsepc/epc.conf.example index 7fabca584..02ef797ef 100644 --- a/srsepc/epc.conf.example +++ b/srsepc/epc.conf.example @@ -10,9 +10,9 @@ # tac: 16-bit Tracking Area Code. # mcc: Mobile Country Code # mnc: Mobile Network Code -# mme_bindx_addr: IP subnet to listen for eNB S1 connnections -# apn: Set Access Point Name (APN) -# mme_bind_addr: IP bind addr to listen for eNB S1 connnections +# apn: Set Access Point Name (APN) +# mme_bind_addr: IP bind addr to listen for eNB S1-MME connnections +# dns_addr: DNS server address for the UEs # ##################################################################### [mme] @@ -23,6 +23,7 @@ mcc = 001 mnc = 01 mme_bind_addr = 127.0.1.100 apn = srsapn +dns_addr = 8.8.8.8 ##################################################################### # HSS configuration From b50672b0ef1da4903c3b327f41f6eb935bce6b93 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 28 Mar 2018 16:41:10 +0200 Subject: [PATCH 327/342] fix non-returning function warning --- srsue/src/upper/nas.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 7069f4a23..939db1686 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -376,6 +376,7 @@ bool nas::integrity_check(byte_buffer_t *pdu) return true; } else { nas_log->error("Invalid integrity check PDU size (%d)\n", pdu->N_bytes); + return false; } } From bf25a5a05cfbc56128e2bbd1df00a1c3da18ea52 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 28 Mar 2018 16:46:40 +0200 Subject: [PATCH 328/342] fix handling of log vector in eNB --- srsenb/hdr/enb.h | 2 +- srsenb/hdr/phy/phy.h | 5 +++-- srsenb/src/enb.cc | 5 ++++- srsenb/src/phy/phy.cc | 10 +++++----- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index ff314977a..6d2a78b44 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -188,7 +188,7 @@ private: srslte::logger *logger; srslte::log_filter rf_log; - std::vector phy_log; + std::vector phy_log; srslte::log_filter mac_log; srslte::log_filter rlc_log; srslte::log_filter pdcp_log; diff --git a/srsenb/hdr/phy/phy.h b/srsenb/hdr/phy/phy.h index a1616c268..99b23de0c 100644 --- a/srsenb/hdr/phy/phy.h +++ b/srsenb/hdr/phy/phy.h @@ -28,6 +28,7 @@ #define ENBPHY_H #include "srslte/common/log.h" +#include "srslte/common/log_filter.h" #include "phy/txrx.h" #include "phy/phch_worker.h" #include "phy/phch_common.h" @@ -54,8 +55,8 @@ class phy : public phy_interface_mac, public: phy(); - bool init(phy_args_t *args, phy_cfg_t *common_cfg, srslte::radio *radio_handler, mac_interface_phy *mac, srslte::log* log_h); - bool init(phy_args_t *args, phy_cfg_t *common_cfg, srslte::radio *radio_handler, mac_interface_phy *mac, std::vector log_vec); + bool init(phy_args_t *args, phy_cfg_t *common_cfg, srslte::radio *radio_handler, mac_interface_phy *mac, srslte::log_filter* log_h); + bool init(phy_args_t *args, phy_cfg_t *common_cfg, srslte::radio *radio_handler, mac_interface_phy *mac, std::vector log_vec); void stop(); /* MAC->PHY interface */ diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 564775e5e..6e5e06669 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -67,6 +67,9 @@ enb::enb() : started(false) { enb::~enb() { + for (uint32_t i = 0; i < phy_log.size(); i++) { + delete (phy_log[i]); + } } bool enb::init(all_args_t *args_) @@ -89,7 +92,7 @@ bool enb::init(all_args_t *args_) char tmp[16]; sprintf(tmp, "PHY%d",i); mylog->init(tmp, logger, true); - phy_log.push_back((void*) mylog); + phy_log.push_back(mylog); } mac_log.init("MAC ", logger, true); rlc_log.init("RLC ", logger); diff --git a/srsenb/src/phy/phy.cc b/srsenb/src/phy/phy.cc index d47998fa9..08b89d77f 100644 --- a/srsenb/src/phy/phy.cc +++ b/srsenb/src/phy/phy.cc @@ -92,12 +92,12 @@ void phy::parse_config(phy_cfg_t* cfg) bool phy::init(phy_args_t *args, phy_cfg_t *cfg, srslte::radio* radio_handler_, - mac_interface_phy *mac, - srslte::log* log_h) + mac_interface_phy *mac, + srslte::log_filter* log_h) { - std::vector log_vec; + std::vector log_vec; for (int i=0;inof_phy_threads;i++) { - log_vec.push_back((void*)log_h); + log_vec.push_back(log_h); } init(args, cfg, radio_handler_, mac, log_vec); return true; @@ -107,7 +107,7 @@ bool phy::init(phy_args_t *args, phy_cfg_t *cfg, srslte::radio* radio_handler_, mac_interface_phy *mac, - std::vector log_vec) + std::vector log_vec) { mlockall(MCL_CURRENT | MCL_FUTURE); From fffda82f1ee3c48175274e2ff67fcecc244ef06c Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 23 Mar 2018 16:41:37 +0100 Subject: [PATCH 329/342] increase size of bytebuffer to compensate header, add helper to get remaining size --- lib/include/srslte/common/common.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/include/srslte/common/common.h b/lib/include/srslte/common/common.h index 8089634b7..de9f6d5aa 100644 --- a/lib/include/srslte/common/common.h +++ b/lib/include/srslte/common/common.h @@ -147,6 +147,11 @@ public: { return msg-buffer; } + // Returns the remaining space from what is reported to be the length of msg + uint32_t get_tailroom() + { + return (sizeof(buffer) - (msg-buffer) - N_bytes); + } long get_latency_us() { #ifdef ENABLE_TIMESTAMP From 6063888cc5d7435f3f597cf0938154e22c63099a Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 27 Mar 2018 21:33:26 +0200 Subject: [PATCH 330/342] protect memcpy's in rx sdu reassembly with boundary checks --- lib/src/upper/rlc_am.cc | 75 +++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 26 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 5c7cb72ea..d100508d1 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -128,10 +128,10 @@ void rlc_am::reset() reordering_timeout.reset(); if(tx_sdu) { pool->deallocate(tx_sdu); - tx_sdu = NULL; } - if(rx_sdu) - rx_sdu->reset(); + if(rx_sdu) { + pool->deallocate(rx_sdu); + } vt_a = 0; vt_ms = RLC_AM_WINDOW_SIZE; @@ -827,6 +827,12 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) rrc->get_rb_name(lcid).c_str(), to_move, pdu_space, head_len); } + // Make sure, at least one SDU (segment) has been added until this point + if (pdu->N_bytes == 0) { + log->error("Generated empty RLC PDU.\n"); + return 0; + } + if(tx_sdu) header.fi |= RLC_FI_FIELD_NOT_END_ALIGNED; // Last byte does not correspond to last byte of SDU @@ -848,7 +854,6 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) // Set SN header.sn = vt_s; vt_s = (vt_s + 1)%MOD; - log->info("%s PDU scheduled for tx. SN: %d (%d B)\n", rrc->get_rb_name(lcid).c_str(), header.sn, pdu->N_bytes); // Place PDU in tx_window, write header and TX tx_window[header.sn].buf = pdu; @@ -859,6 +864,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) uint8_t *ptr = payload; rlc_am_write_data_pdu_header(&header, &ptr); memcpy(ptr, pdu->msg, pdu->N_bytes); + log->info_hex(payload, pdu->N_bytes, "%s PDU scheduled for tx. SN: %d (%d B)\n", rrc->get_rb_name(lcid).c_str(), header.sn, pdu->N_bytes); debug_state(); return (ptr-payload) + pdu->N_bytes; @@ -868,8 +874,8 @@ void rlc_am::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_h { std::map::iterator it; - log->info_hex(payload, nof_bytes, "%s Rx data PDU SN: %d", - rrc->get_rb_name(lcid).c_str(), header.sn); + log->info_hex(payload, nof_bytes, "%s Rx data PDU SN: %d (%d B), %s", + rrc->get_rb_name(lcid).c_str(), header.sn, nof_bytes, rlc_fi_field_text[header.fi]); if(!inside_rx_window(header.sn)) { if(header.p) { @@ -1157,38 +1163,55 @@ void rlc_am::reassemble_rx_sdus() #endif } } + // Iterate through rx_window, assembling and delivering SDUs while(rx_window.end() != rx_window.find(vr_r)) { // Handle any SDU segments for(uint32_t i=0; imsg[rx_sdu->N_bytes], rx_window[vr_r].buf->msg, len); - rx_sdu->N_bytes += len; - rx_window[vr_r].buf->msg += len; - rx_window[vr_r].buf->N_bytes -= len; - log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU", rrc->get_rb_name(lcid).c_str()); - rx_sdu->set_timestamp(); - pdcp->write_pdu(lcid, rx_sdu); - rx_sdu = pool_allocate; - if (!rx_sdu) { + uint32_t len = rx_window[vr_r].header.li[i]; + if (rx_sdu->get_tailroom() >= len) { + memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_r].buf->msg, len); + rx_sdu->N_bytes += len; + rx_window[vr_r].buf->msg += len; + rx_window[vr_r].buf->N_bytes -= len; + log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU (%d B)", rrc->get_rb_name(lcid).c_str(), rx_sdu->N_bytes); + rx_sdu->set_timestamp(); + 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); + log->console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (2)\n"); + exit(-1); #else - log->error("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (2)\n"); - return; + log->error("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (2)\n"); + return; #endif + } + } else { + log->error("Cannot fit RLC PDU in SDU buffer, dropping both.\n"); + pool->deallocate(rx_sdu); + pool->deallocate(rx_window[vr_r].buf); + rx_window.erase(vr_r); } } // Handle last segment - memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_r].buf->msg, rx_window[vr_r].buf->N_bytes); - rx_sdu->N_bytes += rx_window[vr_r].buf->N_bytes; - if(rlc_am_end_aligned(rx_window[vr_r].header.fi)) - { - log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU", rrc->get_rb_name(lcid).c_str()); + uint32_t len = rx_window[vr_r].buf->N_bytes; + if (rx_sdu->get_tailroom() >= len) { + memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_r].buf->msg, len); + rx_sdu->N_bytes += rx_window[vr_r].buf->N_bytes; + } else { + log->error("Cannot fit RLC PDU in SDU buffer, dropping both.\n"); + pool->deallocate(rx_sdu); + pool->deallocate(rx_window[vr_r].buf); + rx_window.erase(vr_r); + } + + if(rlc_am_end_aligned(rx_window[vr_r].header.fi)) { + log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU (%d B)", rrc->get_rb_name(lcid).c_str(), rx_sdu->N_bytes); rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; @@ -1250,7 +1273,7 @@ void rlc_am::print_rx_segments() 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; + ss << " SN:" << segit->header.sn << " SO:" << segit->header.so << " N:" << segit->buf->N_bytes << " N_li: " << segit->header.N_li << std::endl; } } log->debug("%s\n", ss.str().c_str()); From 6184a8b6aad619884b1f39d3182fcfd1d8ac5ce5 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 28 Mar 2018 18:17:34 +0100 Subject: [PATCH 331/342] Fixed bug in GUTI allocation for multiple UEs. --- srsepc/src/mme/s1ap.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 3fe34806c..4b1bbd688 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -78,7 +78,7 @@ s1ap::init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log, hss_interface_s1 m_s1ap_args = s1ap_args; srslte::s1ap_mccmnc_to_plmn(s1ap_args.mcc, s1ap_args.mnc, &m_plmn); - m_next_m_tmsi = 0xF000; + m_next_m_tmsi = rand(); //Init log m_s1ap_log = s1ap_log; @@ -542,8 +542,8 @@ s1ap::activate_eps_bearer(uint64_t imsi, uint8_t ebi) uint32_t s1ap::allocate_m_tmsi(uint64_t imsi) { - // uint32_t m_tmsi = m_next_m_tmsi++; - uint32_t m_tmsi = m_next_m_tmsi; + uint32_t m_tmsi = m_next_m_tmsi++; + //uint32_t m_tmsi = m_next_m_tmsi; m_tmsi_to_imsi.insert(std::pair(m_tmsi,imsi)); m_s1ap_log->debug("Allocated M-TMSI 0x%x to IMSI %015lu,\n",m_tmsi,imsi); return m_tmsi; From 08212a6b1344ea4e22641490a8fb755f0d0e8e06 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 29 Mar 2018 10:27:19 +0200 Subject: [PATCH 332/342] fix compile warning due to missing async thread --- lib/src/phy/rf/rf_uhd_imp.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index b4b0cfcd6..1c09b7990 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -35,6 +35,8 @@ #include "srslte/phy/rf/rf.h" #include "uhd_c_api.h" +#define HAVE_ASYNC_THREAD 0 + typedef struct { char *devname; uhd_usrp_handle usrp; @@ -87,6 +89,7 @@ static void log_late(rf_uhd_handler_t *h, bool is_rx) { } } +#if HAVE_ASYNC_THREAD static void log_underflow(rf_uhd_handler_t *h) { if (h->uhd_error_handler) { srslte_rf_error_t error; @@ -95,6 +98,7 @@ static void log_underflow(rf_uhd_handler_t *h) { h->uhd_error_handler(error); } } +#endif static void log_rx_error(rf_uhd_handler_t *h) { if (h->uhd_error_handler) { @@ -109,6 +113,7 @@ static void log_rx_error(rf_uhd_handler_t *h) { } } +#if HAVE_ASYNC_THREAD static void* async_thread(void *h) { rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; uhd_async_metadata_handle md; @@ -135,6 +140,7 @@ static void* async_thread(void *h) { uhd_async_metadata_free(&md); return NULL; } +#endif void rf_uhd_suppress_stdout(void *h) { rf_uhd_register_msg_handler_c(suppress_handler); @@ -570,13 +576,14 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels) rf_uhd_set_rx_gain(handler, max_gain*0.7); uhd_meta_range_free(&gain_range); +#if HAVE_ASYNC_THREAD // Start low priority thread to receive async commands - /* handler->async_thread_running = true; if (pthread_create(&handler->async_thread, NULL, async_thread, handler)) { perror("pthread_create"); return -1; - }*/ + } +#endif /* Restore priorities */ uhd_set_thread_priority(0, false); From ded550b793053896262e170cae02f6e1bb95f77d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 29 Mar 2018 10:28:36 +0200 Subject: [PATCH 333/342] remove unneeded boost includes --- srsenb/src/enb.cc | 1 - srsepc/hdr/mme/mme_gtpc.h | 1 - srsepc/src/hss/hss.cc | 1 - srsepc/src/spgw/spgw.cc | 1 - 4 files changed, 4 deletions(-) diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 6e5e06669..df9ea9a45 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -25,7 +25,6 @@ */ #include -#include #include #include "enb.h" diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index 23e6acf0a..f41172cce 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -29,7 +29,6 @@ #include "srslte/common/log.h" #include "srslte/common/log_filter.h" #include "srslte/common/buffer_pool.h" -#include #include "srslte/asn1/gtpc.h" #include "mme/s1ap_common.h" namespace srsepc diff --git a/srsepc/src/hss/hss.cc b/srsepc/src/hss/hss.cc index a3bc797b4..703928270 100644 --- a/srsepc/src/hss/hss.cc +++ b/srsepc/src/hss/hss.cc @@ -28,7 +28,6 @@ #include #include #include -#include #include "hss/hss.h" #include "srslte/common/security.h" diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index 191e131df..1ef33a8f0 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -26,7 +26,6 @@ #include #include -#include #include #include #include From 9c006e45859f13cf1e9fe62076035393ca462894 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 29 Mar 2018 12:12:15 +0200 Subject: [PATCH 334/342] remove boost system dependency --- CMakeLists.txt | 1 - README.md | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 98023d7b5..1fde57f27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -171,7 +171,6 @@ if(ENABLE_SRSUE OR ENABLE_SRSENB OR ENABLE_SRSEPC) set(BOOST_REQUIRED_COMPONENTS program_options - system ) if(UNIX AND EXISTS "/usr/lib64") list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix diff --git a/README.md b/README.md index 1567c7c71..a8f186a62 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ Build Instructions For example, on Ubuntu 17.04, one can install the required libraries with: ``` -sudo apt-get install cmake libfftw3-dev libmbedtls-dev libboost-program-options-dev libboost-thread-dev libconfig++-dev libsctp-dev +sudo apt-get install cmake libfftw3-dev libmbedtls-dev libboost-program-options-dev libconfig++-dev libsctp-dev ``` Note that depending on your flavor and version of Linux, the actual package names may be different. From 5f9e0adbb6986b7a6e80ffd6550a14b762144151 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 29 Mar 2018 11:47:01 +0100 Subject: [PATCH 335/342] Making sure cmath is included for std::pow --- srsepc/src/mme/s1ap_nas_transport.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index eb64a09eb..f64e4ff0d 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -25,6 +25,7 @@ */ #include +#include #include "mme/s1ap.h" #include "mme/s1ap_nas_transport.h" #include "srslte/common/security.h" From 308efd4fdc74ff23487773955c256111e3f33efd Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 29 Mar 2018 12:02:16 +0100 Subject: [PATCH 336/342] Avoid overflow on M-TMSI allocation. --- srsepc/src/mme/s1ap.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 4b1bbd688..0dce45c41 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -542,8 +542,9 @@ s1ap::activate_eps_bearer(uint64_t imsi, uint8_t ebi) uint32_t s1ap::allocate_m_tmsi(uint64_t imsi) { - uint32_t m_tmsi = m_next_m_tmsi++; - //uint32_t m_tmsi = m_next_m_tmsi; + uint32_t m_tmsi = m_next_m_tmsi; + m_next_m_tmsi = (m_next_m_tmsi + 1) % UINT32_MAX; + m_tmsi_to_imsi.insert(std::pair(m_tmsi,imsi)); m_s1ap_log->debug("Allocated M-TMSI 0x%x to IMSI %015lu,\n",m_tmsi,imsi); return m_tmsi; From 3db9ddcd3664450a1623d207d089ddedfac5f306 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 29 Mar 2018 13:44:42 +0200 Subject: [PATCH 337/342] remove various debug prints --- lib/src/common/pdu.cc | 1 - srsue/src/main.cc | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/src/common/pdu.cc b/lib/src/common/pdu.cc index 80db7627d..95d9dde9b 100644 --- a/lib/src/common/pdu.cc +++ b/lib/src/common/pdu.cc @@ -124,7 +124,6 @@ uint8_t* sch_pdu::write_packet(srslte::log *log_h) if (nof_subheaders <= 0 && nof_subheaders < (int)max_subheaders) { log_h->error("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders); - log_h->console("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders); return NULL; } diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 8753e7630..30a3e3b00 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -484,8 +484,7 @@ int main(int argc, char *argv[]) plot_started = true; } } - ue->print_pool(); - sleep(10); + sleep(1); } pthread_cancel(input); metricshub.stop(); From 2cf5acf9c891537b7167208b86b1caa918db229f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 29 Mar 2018 14:48:35 +0200 Subject: [PATCH 338/342] set valgrind options correctly this avoid an ugly valgrind error after executing long sequences of simd code see: https://www.bountysource.com/issues/41603953-temporary-storage-exhausted-when-long-sequence-of-vfmadd231ps-instructions-to-be-executed --- CMakeLists.txt | 2 -- CTestConfig.cmake | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1fde57f27..52716499e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,8 +41,6 @@ include(SRSLTEVersion) #sets version information include(SRSLTEPackage) #setup cpack include(CTest) -set(CTEST_MEMORYCHECK_COMMAND valgrind) -set(CTEST_MEMORYCHECK_COMMAND_OPTIONS "--trace-children=yes --leak-check=full" ) configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/CTestCustom.cmake.in" diff --git a/CTestConfig.cmake b/CTestConfig.cmake index 1c4aa5735..d8e316006 100644 --- a/CTestConfig.cmake +++ b/CTestConfig.cmake @@ -11,3 +11,4 @@ set(CTEST_DROP_METHOD "http") set(CTEST_DROP_SITE "my.cdash.org") set(CTEST_DROP_LOCATION "/submit.php?project=srsLTE") set(CTEST_DROP_SITE_CDASH TRUE) +set(VALGRIND_COMMAND_OPTIONS "--trace-children=yes --leak-check=full --show-reachable=yes --vex-guest-max-insns=25") \ No newline at end of file From 9b689d479fc7feaee47380ee938060095bf01926 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 29 Mar 2018 16:47:10 +0200 Subject: [PATCH 339/342] bumping version number to 18.03 --- cmake/modules/SRSLTEVersion.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/SRSLTEVersion.cmake b/cmake/modules/SRSLTEVersion.cmake index fec6ab21f..30d2707b0 100644 --- a/cmake/modules/SRSLTEVersion.cmake +++ b/cmake/modules/SRSLTEVersion.cmake @@ -18,7 +18,7 @@ # and at http://www.gnu.org/licenses/. # -SET(SRSLTE_VERSION_MAJOR 17) -SET(SRSLTE_VERSION_MINOR 12) +SET(SRSLTE_VERSION_MAJOR 18) +SET(SRSLTE_VERSION_MINOR 3) SET(SRSLTE_VERSION_PATCH 0) SET(SRSLTE_VERSION_STRING "${SRSLTE_VERSION_MAJOR}.${SRSLTE_VERSION_MINOR}.${SRSLTE_VERSION_PATCH}") From 49da57c8a14b59e227ea5ff533dd34d0c3538882 Mon Sep 17 00:00:00 2001 From: Joseph Giovatto Date: Mon, 19 Feb 2018 22:03:07 -0500 Subject: [PATCH 340/342] Changed log methods to take string literal vs string object to allow for format checking and save on object copy. Fixed log format specifier warnings. --- CMakeLists.txt | 2 +- lib/include/srslte/common/log.h | 10 +++++----- lib/include/srslte/common/log_filter.h | 10 +++++----- lib/src/common/log_filter.cc | 20 ++++++++++---------- lib/src/upper/rlc_am.cc | 4 ++-- srsenb/src/enb.cc | 2 +- srsenb/src/phy/phch_worker.cc | 4 ++-- srsenb/src/phy/txrx.cc | 2 +- srsenb/src/upper/rrc.cc | 8 ++++---- srsepc/src/mme/s1ap_nas_transport.cc | 8 ++++---- srsue/src/mac/proc_phr.cc | 4 ++-- srsue/src/phy/phch_recv.cc | 6 +++--- srsue/src/phy/prach.cc | 2 +- srsue/src/ue_base.cc | 2 +- srsue/src/upper/nas.cc | 2 +- srsue/src/upper/rrc.cc | 6 +++--- srsue/src/upper/usim.cc | 16 ++++++++-------- 17 files changed, 54 insertions(+), 54 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 52716499e..290754ee3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -226,7 +226,7 @@ macro(ADD_CXX_COMPILER_FLAG_IF_AVAILABLE flag have) endmacro(ADD_CXX_COMPILER_FLAG_IF_AVAILABLE) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${GCC_ARCH} -Wall -Wno-comment -Wno-reorder -Wno-unused-but-set-variable -Wno-unused-variable -std=c++03") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${GCC_ARCH} -Wall -Wno-comment -Wno-reorder -Wno-unused-but-set-variable -Wno-unused-variable -Wformat -std=c++03") find_package(SSE) if (HAVE_AVX2) diff --git a/lib/include/srslte/common/log.h b/lib/include/srslte/common/log.h index 360482c47..45c359629 100644 --- a/lib/include/srslte/common/log.h +++ b/lib/include/srslte/common/log.h @@ -122,11 +122,11 @@ public: } // Pure virtual methods for logging - virtual void console(std::string message, ...) = 0; - virtual void error(std::string message, ...) = 0; - virtual void warning(std::string message, ...) = 0; - virtual void info(std::string message, ...) = 0; - virtual void debug(std::string message, ...) = 0; + virtual void console(const char * message, ...) __attribute__ ((format (printf, 2, 3))) = 0; + virtual void error(const char * message, ...) __attribute__ ((format (printf, 2, 3))) = 0; + virtual void warning(const char * message, ...) __attribute__ ((format (printf, 2, 3))) = 0; + virtual void info(const char * message, ...) __attribute__ ((format (printf, 2, 3))) = 0; + virtual void debug(const char * message, ...) __attribute__ ((format (printf, 2, 3))) = 0; // Same with hex dump virtual void error_hex(uint8_t *hex, int size, std::string message, ...){error("error_hex not implemented.\n");} diff --git a/lib/include/srslte/common/log_filter.h b/lib/include/srslte/common/log_filter.h index 7e4014190..430a59199 100644 --- a/lib/include/srslte/common/log_filter.h +++ b/lib/include/srslte/common/log_filter.h @@ -57,11 +57,11 @@ public: void init(std::string layer, logger *logger_, bool tti=false); - void console(std::string message, ...); - void error(std::string message, ...); - void warning(std::string message, ...); - void info(std::string message, ...); - void debug(std::string message, ...); + void console(const char * message, ...); + void error(const char * message, ...); + void warning(const char * message, ...); + void info(const char * message, ...); + void debug(const char * message, ...); void error_hex(uint8_t *hex, int size, std::string message, ...); void warning_hex(uint8_t *hex, int size, std::string message, ...); diff --git a/lib/src/common/log_filter.cc b/lib/src/common/log_filter.cc index 8b72a3c2b..b79e222e7 100644 --- a/lib/src/common/log_filter.cc +++ b/lib/src/common/log_filter.cc @@ -135,55 +135,55 @@ void log_filter::all_log(srslte::LOG_LEVEL_ENUM level, } } -void log_filter::console(std::string message, ...) { +void log_filter::console(const char * message, ...) { char *args_msg; va_list args; va_start(args, message); - if(vasprintf(&args_msg, message.c_str(), args) > 0) + if(vasprintf(&args_msg, message, args) > 0) printf("%s",args_msg); // Print directly to stdout va_end(args); free(args_msg); } -void log_filter::error(std::string message, ...) { +void log_filter::error(const char * message, ...) { if (level >= LOG_LEVEL_ERROR) { char *args_msg; va_list args; va_start(args, message); - if(vasprintf(&args_msg, message.c_str(), args) > 0) + if(vasprintf(&args_msg, message, args) > 0) all_log(LOG_LEVEL_ERROR, tti, args_msg); va_end(args); free(args_msg); } } -void log_filter::warning(std::string message, ...) { +void log_filter::warning(const char * message, ...) { if (level >= LOG_LEVEL_WARNING) { char *args_msg; va_list args; va_start(args, message); - if(vasprintf(&args_msg, message.c_str(), args) > 0) + if(vasprintf(&args_msg, message, args) > 0) all_log(LOG_LEVEL_WARNING, tti, args_msg); va_end(args); free(args_msg); } } -void log_filter::info(std::string message, ...) { +void log_filter::info(const char * message, ...) { if (level >= LOG_LEVEL_INFO) { char *args_msg; va_list args; va_start(args, message); - if(vasprintf(&args_msg, message.c_str(), args) > 0) + if(vasprintf(&args_msg, message, args) > 0) all_log(LOG_LEVEL_INFO, tti, args_msg); va_end(args); free(args_msg); } } -void log_filter::debug(std::string message, ...) { +void log_filter::debug(const char * message, ...) { if (level >= LOG_LEVEL_DEBUG) { char *args_msg; va_list args; va_start(args, message); - if(vasprintf(&args_msg, message.c_str(), args) > 0) + if(vasprintf(&args_msg, message, args) > 0) all_log(LOG_LEVEL_DEBUG, tti, args_msg); va_end(args); free(args_msg); diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index d100508d1..2537ee48c 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -342,7 +342,7 @@ int rlc_am::read_pdu(uint8_t *payload, uint32_t nof_bytes) pthread_mutex_lock(&mutex); log->debug("MAC opportunity - %d bytes\n", nof_bytes); - log->debug("tx_window size - %d PDUs\n", tx_window.size()); + log->debug("tx_window size - %zu PDUs\n", tx_window.size()); // Tx STATUS if requested if(do_status && !status_prohibited()) { @@ -698,7 +698,7 @@ int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t r if(pdu_len > (int)nof_bytes) { log->error("%s Retx PDU segment length error. Available: %d, Used: %d\n", rrc->get_rb_name(lcid).c_str(), nof_bytes, pdu_len); - log->debug("%s Retx PDU segment length error. Header len: %d, Payload len: %d, N_li: %d\n", + log->debug("%s Retx PDU segment length error. Header len: %ld, Payload len: %d, N_li: %d\n", rrc->get_rb_name(lcid).c_str(), (ptr-payload), len, new_header.N_li); } return pdu_len; diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index df9ea9a45..2d3466522 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -297,7 +297,7 @@ void enb::handle_rf_msg(srslte_rf_error_t error) str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); str.erase(std::remove(str.begin(), str.end(), '\r'), str.end()); str.push_back('\n'); - rf_log.info(str); + rf_log.info(str.c_str()); } } diff --git a/srsenb/src/phy/phch_worker.cc b/srsenb/src/phy/phch_worker.cc index 8013a7d5c..5524be442 100644 --- a/srsenb/src/phy/phch_worker.cc +++ b/srsenb/src/phy/phch_worker.cc @@ -227,7 +227,7 @@ void phch_worker::set_conf_dedicated_ack(uint16_t rnti, bool ack){ if (ue_db.count(rnti)) { ue_db[rnti].dedicated_ack = ack; } else { - Error("Setting dedicated ack: rnti=0x%x does not exist\n"); + Error("Setting dedicated ack: rnti=0x%x does not exist\n", rnti); } pthread_mutex_unlock(&mutex); } @@ -309,7 +309,7 @@ void phch_worker::set_config_dedicated(uint16_t rnti, ue_db[rnti].dedicated.pdsch_cnfg_ded = dedicated->pdsch_cnfg_ded; } } else { - Error("Setting config dedicated: rnti=0x%x does not exist\n"); + Error("Setting config dedicated: rnti=0x%x does not exist\n", rnti); } pthread_mutex_unlock(&mutex); } diff --git a/srsenb/src/phy/txrx.cc b/srsenb/src/phy/txrx.cc index fbc96ea72..32c8aea00 100644 --- a/srsenb/src/phy/txrx.cc +++ b/srsenb/src/phy/txrx.cc @@ -125,7 +125,7 @@ void txrx::run_thread() srslte_timestamp_copy(&tx_time, &rx_time); srslte_timestamp_add(&tx_time, 0, HARQ_DELAY_MS*1e-3); - Debug("Settting TTI=%d, tx_mutex=%d, tx_time=%d:%f to worker %d\n", + Debug("Settting TTI=%d, tx_mutex=%d, tx_time=%ld:%f to worker %d\n", tti, tx_mutex_cnt, tx_time.full_secs, tx_time.frac_secs, worker->get_id()); diff --git a/srsenb/src/upper/rrc.cc b/srsenb/src/upper/rrc.cc index e025dfca4..9fe1773f7 100644 --- a/srsenb/src/upper/rrc.cc +++ b/srsenb/src/upper/rrc.cc @@ -225,7 +225,7 @@ void rrc::add_user(uint16_t rnti) pdcp->add_user(rnti); rrc_log->info("Added new user rnti=0x%x\n", rnti); } else { - rrc_log->error("Adding user rnti=0x%x (already exists)\n"); + rrc_log->error("Adding user rnti=0x%x (already exists)\n", rnti); } pthread_mutex_unlock(&user_mutex); } @@ -584,7 +584,7 @@ void rrc::parse_ul_ccch(uint16_t rnti, byte_buffer_t *pdu) if (users[rnti].is_idle()) { old_rnti = ul_ccch_msg.msg.rrc_con_reest_req.ue_id.c_rnti; if (users.count(old_rnti)) { - rrc_log->error("Not supported: ConnectionReestablishment. Sending Connection Reject\n", old_rnti); + rrc_log->error("Not supported: ConnectionReestablishment for rnti=0x%x. Sending Connection Reject\n", old_rnti); users[rnti].send_connection_reest_rej(); rem_user_thread(old_rnti); } else { @@ -649,7 +649,7 @@ void rrc::run_thread() pthread_mutex_lock(&user_mutex); break; default: - rrc_log->error("Rx PDU with invalid bearer id: %s", p.lcid); + rrc_log->error("Rx PDU with invalid bearer id: %d", p.lcid); break; } } else { @@ -799,7 +799,7 @@ bool rrc::ue::is_timeout() int64_t deadline = deadline_s*1e6 + deadline_us; int64_t elapsed = t[0].tv_sec*1e6 + t[0].tv_usec; if (elapsed > deadline && elapsed > 0) { - parent->rrc_log->warning("User rnti=0x%x expired %s deadline: %d:%d>%d:%d us\n", + parent->rrc_log->warning("User rnti=0x%x expired %s deadline: %ld:%ld>%d:%d us\n", rnti, deadline_str, t[0].tv_sec, t[0].tv_usec, deadline_s, deadline_us); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index f64e4ff0d..5d6922554 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -1128,13 +1128,13 @@ s1ap_nas_transport::handle_esm_information_response(srslte::byte_buffer_t *nas_m m_s1ap_log->info("ESM Info: EPS bearer id %d\n",esm_info_resp.eps_bearer_id); if(esm_info_resp.apn_present) { - m_s1ap_log->info("ESM Info: APN %s\n",esm_info_resp.eps_bearer_id); - m_s1ap_log->console("ESM Info: APN %s\n",esm_info_resp.eps_bearer_id); + m_s1ap_log->info("ESM Info: APN %d\n",esm_info_resp.eps_bearer_id); + m_s1ap_log->console("ESM Info: APN %d\n",esm_info_resp.eps_bearer_id); } if(esm_info_resp.protocol_cnfg_opts_present) { - m_s1ap_log->info("ESM Info: %d Protocol Configuration Options %s\n",esm_info_resp.protocol_cnfg_opts.N_opts); - m_s1ap_log->console("ESM Info: %d Protocol Configuration Options %s\n",esm_info_resp.protocol_cnfg_opts.N_opts); + m_s1ap_log->info("ESM Info: %d Protocol Configuration Options\n",esm_info_resp.protocol_cnfg_opts.N_opts); + m_s1ap_log->console("ESM Info: %d Protocol Configuration Options\n",esm_info_resp.protocol_cnfg_opts.N_opts); } //FIXME The packging of GTP-C messages is not ready. diff --git a/srsue/src/mac/proc_phr.cc b/srsue/src/mac/proc_phr.cc index 54c1ec1ce..3eb7c82f5 100644 --- a/srsue/src/mac/proc_phr.cc +++ b/srsue/src/mac/proc_phr.cc @@ -91,7 +91,7 @@ void phr_proc::timer_expired(uint32_t timer_id) { } else if (timer_id == timer_prohibit_id) { int pathloss_db = liblte_rrc_dl_pathloss_change_num[mac_cfg->main.phr_cnfg.dl_pathloss_change]; if (pathloss_changed()) { - Info("PHR: Triggered by pathloss difference. cur_pathloss_db=%f (timer expired)\n", last_pathloss_db); + Info("PHR: Triggered by pathloss difference. cur_pathloss_db=%d (timer expired)\n", last_pathloss_db); phr_is_triggered = true; } } else { @@ -132,7 +132,7 @@ void phr_proc::step(uint32_t tti) } if (pathloss_changed() && timers_db->get(timer_prohibit_id)->is_expired()) { - Info("PHR: Triggered by pathloss difference. cur_pathloss_db=%f\n", last_pathloss_db); + Info("PHR: Triggered by pathloss difference. cur_pathloss_db=%d\n", last_pathloss_db); phr_is_triggered = true; } } diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 0df792fd5..ab550aaa2 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -275,7 +275,7 @@ void phch_recv::cell_search_inc() phy_state = IDLE; rrc->earfcn_end(); } else { - Info("SYNC: Cell Search idx %d/%d\n", cur_earfcn_index, earfcn.size()); + Info("SYNC: Cell Search idx %d/%zu\n", cur_earfcn_index, earfcn.size()); if (current_earfcn != earfcn[cur_earfcn_index]) { current_earfcn = earfcn[cur_earfcn_index]; set_frequency(); @@ -297,7 +297,7 @@ void phch_recv::cell_search_start() { Warning("SYNC: Can't start cell search procedure while camping on cell\n"); } else { if (earfcn.size() > 0) { - Info("SYNC: Starting Cell Search procedure in %d EARFCNs...\n", earfcn.size()); + Info("SYNC: Starting Cell Search procedure in %zu EARFCNs...\n", earfcn.size()); cell_search_next(true); } else { Info("SYNC: Empty EARFCN list. Stopping cell search...\n"); @@ -1502,7 +1502,7 @@ void phch_recv::intra_measure::rem_cell(int pci) { if (active_pci.size() == 0) { receive_enabled = false; } - Info("INTRA: Stopping intra-frequency measurement for pci=%d. Number of cells: %d\n", pci, active_pci.size()); + Info("INTRA: Stopping intra-frequency measurement for pci=%d. Number of cells: %zu\n", pci, active_pci.size()); } else { Warning("INTRA: Requested to stop non-existing intra-frequency measurement for PCI=%d\n", pci); } diff --git a/srsue/src/phy/prach.cc b/srsue/src/phy/prach.cc index fdf925642..a1bf96c85 100644 --- a/srsue/src/phy/prach.cc +++ b/srsue/src/phy/prach.cc @@ -201,7 +201,7 @@ void prach::send(srslte::radio *radio_handler, float cfo, float pathloss, srslte float scale = sqrtf(pow(10,tx_power/10)/digital_power); srslte_vec_sc_prod_cfc(signal_buffer, scale, signal_buffer, len); - log_h->console("PRACH: Pathloss=%.2f dB, Target power %.2f dBm, TX_power %.2f dBm, TX_gain %.1f dB\n", + log_h->console("PRACH: Pathloss=%.2f dB, Target power %.2f dBm, TX_power %.2f dBm, TX_gain %.1f dB, scale %.2f\n", pathloss, target_power_dbm, tx_power, radio_handler->get_tx_gain(), scale); } else { diff --git a/srsue/src/ue_base.cc b/srsue/src/ue_base.cc index a4264a099..71430fc9f 100644 --- a/srsue/src/ue_base.cc +++ b/srsue/src/ue_base.cc @@ -104,7 +104,7 @@ void ue_base::handle_rf_msg(srslte_rf_error_t error) str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); str.erase(std::remove(str.begin(), str.end(), '\r'), str.end()); str.push_back('\n'); - rf_log.info(str); + rf_log.info(str.c_str()); } } diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 939db1686..5b7f40920 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -682,7 +682,7 @@ void nas::parse_identity_request(uint32_t lcid, byte_buffer_t *pdu) { usim->get_imei_vec(id_resp.mobile_id.imei, 15); break; default: - nas_log->error("Unhandled ID type: %d\n"); + nas_log->error("Unhandled ID type: %d\n", id_req.id_type); pool->deallocate(pdu); return; } diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index e419ea710..4dde6361d 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1680,7 +1680,7 @@ void rrc::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { parse_dl_dcch(lcid, pdu); break; default: - rrc_log->error("RX PDU with invalid bearer id: %s", lcid); + rrc_log->error("RX PDU with invalid bearer id: %d", lcid); break; } } @@ -2891,8 +2891,8 @@ void rrc::rrc_meas::parse_meas_config(LIBLTE_RRC_MEAS_CONFIG_STRUCT *cfg) log_h->info("MEAS: Added measObjectId=%d, earfcn=%d, q_offset=%f, pci=%d, offset_cell=%f\n", cfg->meas_obj_to_add_mod_list.meas_obj_list[i].meas_obj_id, dst_obj->earfcn, dst_obj->q_offset, - dst_obj->cells[src_obj->cells_to_add_mod_list[j].cell_idx].q_offset, - dst_obj->cells[src_obj->cells_to_add_mod_list[j].cell_idx].pci); + dst_obj->cells[src_obj->cells_to_add_mod_list[j].cell_idx].pci, + dst_obj->cells[src_obj->cells_to_add_mod_list[j].cell_idx].q_offset); } diff --git a/srsue/src/upper/usim.cc b/srsue/src/upper/usim.cc index b9f4fda0e..d344734ba 100644 --- a/srsue/src/upper/usim.cc +++ b/srsue/src/upper/usim.cc @@ -49,8 +49,8 @@ void usim::init(usim_args_t *args, srslte::log *usim_log_) if(32 == args->op.length()) { str_to_hex(args->op, op); } else { - usim_log->error("Invalid length for OP: %d should be %d", args->op.length(), 32); - usim_log->console("Invalid length for OP: %d should be %d", args->op.length(), 32); + usim_log->error("Invalid length for OP: %zu should be %d", args->op.length(), 32); + usim_log->console("Invalid length for OP: %zu should be %d", args->op.length(), 32); } if(15 == args->imsi.length()) { @@ -61,8 +61,8 @@ void usim::init(usim_args_t *args, srslte::log *usim_log_) imsi += imsi_c[i] - '0'; } } else { - usim_log->error("Invalid length for ISMI: %d should be %d", args->imsi.length(), 15); - usim_log->console("Invalid length for IMSI: %d should be %d", args->imsi.length(), 15); + usim_log->error("Invalid length for ISMI: %zu should be %d", args->imsi.length(), 15); + usim_log->console("Invalid length for IMSI: %zu should be %d", args->imsi.length(), 15); } if(15 == args->imei.length()) { @@ -73,15 +73,15 @@ void usim::init(usim_args_t *args, srslte::log *usim_log_) imei += imei_c[i] - '0'; } } else { - usim_log->error("Invalid length for IMEI: %d should be %d", args->imei.length(), 15); - usim_log->console("Invalid length for IMEI: %d should be %d", args->imei.length(), 15); + usim_log->error("Invalid length for IMEI: %zu should be %d", args->imei.length(), 15); + usim_log->console("Invalid length for IMEI: %zu should be %d", args->imei.length(), 15); } if(32 == args->k.length()) { str_to_hex(args->k, k); } else { - usim_log->error("Invalid length for K: %d should be %d", args->k.length(), 32); - usim_log->console("Invalid length for K: %d should be %d", args->k.length(), 32); + usim_log->error("Invalid length for K: %zu should be %d", args->k.length(), 32); + usim_log->console("Invalid length for K: %zu should be %d", args->k.length(), 32); } auth_algo = auth_algo_milenage; From ff85e8b77ff8c281429c1f52bdccf663a4071b05 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 29 Mar 2018 17:23:55 +0200 Subject: [PATCH 341/342] fixing remaining printf formating issues --- srsepc/src/mme/s1ap_nas_transport.cc | 9 +++++---- srsue/src/phy/phch_recv.cc | 2 +- srsue/src/upper/rrc.cc | 11 ++++++----- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 5d6922554..183815fc6 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -26,6 +26,7 @@ #include #include +#include // for printing uint64_t #include "mme/s1ap.h" #include "mme/s1ap_nas_transport.h" #include "srslte/common/security.h" @@ -185,11 +186,11 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA ue_ctx_t *ue_ctx = m_s1ap->find_ue_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); if(ue_ctx == NULL) { - m_s1ap_log->warning("Received uplink NAS, but could not find UE ECM context. MME-UE S1AP id: %lu\n",mme_ue_s1ap_id); + m_s1ap_log->warning("Received uplink NAS, but could not find UE ECM context. MME-UE S1AP id: %d\n",mme_ue_s1ap_id); return false; } - m_s1ap_log->debug("Received uplink NAS and found UE ECM context. MME-UE S1AP id: %lu\n",mme_ue_s1ap_id); + m_s1ap_log->debug("Received uplink NAS and found UE ECM context. MME-UE S1AP id: %d\n",mme_ue_s1ap_id); ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; @@ -213,7 +214,7 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA //This can happen with integrity protected identity reponse messages if( !(msg_type == LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE && sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY)) { - m_s1ap_log->warning("Uplink NAS: could not find security context for integrity protected message. MME-UE S1AP id: %lu\n",mme_ue_s1ap_id); + m_s1ap_log->warning("Uplink NAS: could not find security context for integrity protected message. MME-UE S1AP id: %d\n",mme_ue_s1ap_id); m_pool->deallocate(nas_msg); return false; } @@ -1092,7 +1093,7 @@ s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, u ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx; ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx; - m_s1ap_log->console("Unpacked Attached Complete Message. IMSI %d\n", emm_ctx->imsi); + m_s1ap_log->console("Unpacked Attached Complete Message. IMSI %" PRIu64 "\n", emm_ctx->imsi); m_s1ap_log->console("Unpacked Activate Default EPS Bearer message. EPS Bearer id %d\n",act_bearer.eps_bearer_id); //ue_ctx->erabs_ctx[act_bearer->eps_bearer_id].enb_fteid; if(act_bearer.eps_bearer_id < 5 || act_bearer.eps_bearer_id > 15) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index ab550aaa2..49b0af307 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1198,7 +1198,7 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx) } cnt++; - log_h->debug("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm, corr-RSRP=%.1f dBm, SNR=%.1f dB\n", + log_h->debug("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm, SNR=%.1f dB\n", cnt, nof_subframes, sf_idx, rsrp, snr); if (cnt >= nof_subframes) { diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 4dde6361d..53e85fac8 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -30,6 +30,7 @@ #include #include #include +#include // for printing uint64_t #include #include "upper/rrc.h" #include "srslte/asn1/liblte_rrc.h" @@ -528,7 +529,7 @@ void rrc::set_serving_cell(uint32_t cell_idx) { // Set new serving cell serving_cell = new_serving_cell; - rrc_log->info("Setting serving cell idx=%d, earfcn=%d, PCI=%d, nof_neighbours=%d\n", + rrc_log->info("Setting serving cell idx=%d, earfcn=%d, PCI=%d, nof_neighbours=%zd\n", cell_idx, serving_cell->get_earfcn(), serving_cell->phy_cell.id, neighbour_cells.size()); } else { @@ -751,7 +752,7 @@ bool rrc::add_neighbour_cell(cell_t *new_cell) { if (ret) { neighbour_cells.push_back(new_cell); } - rrc_log->info("Added neighbour cell EARFCN=%d, PCI=%d, nof_neighbours=%d\n", + rrc_log->info("Added neighbour cell EARFCN=%d, PCI=%d, nof_neighbours=%zd\n", new_cell->get_earfcn(), new_cell->get_pci(), neighbour_cells.size()); sort_neighbour_cells(); return ret; @@ -1634,7 +1635,7 @@ void rrc::send_ul_ccch_msg() ue_cri_ptr[nbytes - i - 1] = pdu->msg[i]; } - rrc_log->debug("Setting UE contention resolution ID: %d\n", uecri); + rrc_log->debug("Setting UE contention resolution ID: %" PRIu64 "\n", uecri); mac->set_contention_id(uecri); rrc_log->info("Sending %s\n", liblte_rrc_ul_ccch_msg_type_text[ul_ccch_msg.msg_type]); @@ -2973,7 +2974,7 @@ void rrc::rrc_meas::parse_meas_config(LIBLTE_RRC_MEAS_CONFIG_STRUCT *cfg) remove_meas_id(cfg->meas_id_to_remove_list[i]); } - log_h->info("nof active measId=%d\n", active.size()); + log_h->info("nof active measId=%zd\n", active.size()); // Measurement identity addition/modification 5.5.2.3 if (cfg->meas_id_to_add_mod_list_present) { @@ -2992,7 +2993,7 @@ void rrc::rrc_meas::parse_meas_config(LIBLTE_RRC_MEAS_CONFIG_STRUCT *cfg) } active[measId->meas_id].object_id = measId->meas_obj_id; active[measId->meas_id].report_id = measId->rep_cnfg_id; - log_h->info("MEAS: %s measId=%d, measObjectId=%d, reportConfigId=%d, timer_id=%d, nof_values=%d\n", + log_h->info("MEAS: %s measId=%d, measObjectId=%d, reportConfigId=%d, timer_id=%d, nof_values=%zd\n", is_new?"Added":"Updated", measId->meas_id, measId->meas_obj_id, measId->rep_cnfg_id, active[measId->meas_id].periodic_timer, active[measId->meas_id].cell_values.size()); } From 2351ced98b5a67179e22527f7dcf81e50876d1fa Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 29 Mar 2018 17:30:52 +0200 Subject: [PATCH 342/342] adding very brief changelog for 18.03 --- CHANGELOG | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 5a57af260..9bed0247c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ Change Log for Releases ============================== +## 18.03 + * Many bug-fixes and improved stability and performance in all parts + ## 17.12 * Added support for MIMO 2x2 in srsENB (i.e. TM3/TM4) * Added srsEPC, a light-weight core network implementation