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/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: diff --git a/lib/include/srslte/common/interfaces_common.h b/lib/include/srslte/common/interfaces_common.h index 1ddcb5150..e7de90ea1 100644 --- a/lib/include/srslte/common/interfaces_common.h +++ b/lib/include/srslte/common/interfaces_common.h @@ -30,6 +30,7 @@ #include "srslte/common/timers.h" #include "srslte/common/security.h" #include "srslte/asn1/liblte_rrc.h" +#include namespace srslte { @@ -37,11 +38,13 @@ namespace srslte { class srslte_nas_config_t { public: - srslte_nas_config_t(uint32_t lcid_ = 0) - :lcid(lcid_) + srslte_nas_config_t(uint32_t lcid_ = 0, std::string apn_ = "") + :lcid(lcid_), + apn(apn_) {} - uint32_t lcid; + uint32_t lcid; + std::string apn; }; 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}; 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; diff --git a/srsepc/epc.conf.example b/srsepc/epc.conf.example index d90e3a6ef..b32a6984a 100644 --- a/srsepc/epc.conf.example +++ b/srsepc/epc.conf.example @@ -11,6 +11,7 @@ # 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] @@ -20,6 +21,7 @@ tac = 0x0007 mcc = 001 mnc = 01 mme_bind_addr = 127.0.1.100 +apn = test123 ##################################################################### # HSS configuration diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index 145a94225..1b5b0ea54 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -91,6 +91,7 @@ typedef struct{ std::string mme_bind_addr; std::string mme_name; std::string dns_addr; + std::string mme_apn; } s1ap_args_t; typedef struct{ @@ -138,6 +139,7 @@ typedef struct{ uint8_t procedure_transaction_id; emm_state_t emm_state; uint32_t mme_ue_s1ap_id; + uint8_t attach_type; } ue_emm_ctx_t; typedef struct{ @@ -162,6 +164,7 @@ typedef struct{ erab_ctx_t erabs_ctx[MAX_ERABS_PER_UE]; bool eit; uint8_t procedure_transaction_id; + uint8_t attach_type; } ue_ctx_t; }//namespace #endif diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index 63253dcb0..b107eb010 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -95,6 +95,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(ue_ecm_ctx_t* ue_ecm_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); void log_unhandled_pdn_con_request_ies(const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT *pdn_con_req); @@ -112,7 +113,5 @@ private: hss_interface_s1ap* m_hss; mme_gtpc* m_mme_gtpc; }; - } //namespace srsepc - #endif //S1AP_NAS_TRANSPORT diff --git a/srsepc/hdr/mme/s1ap_ue_cap_info.h b/srsepc/hdr/mme/s1ap_ue_cap_info.h index 59bb37ea3..4e3b4c14e 100644 --- a/srsepc/hdr/mme/s1ap_ue_cap_info.h +++ b/srsepc/hdr/mme/s1ap_ue_cap_info.h @@ -54,7 +54,5 @@ private: s1ap* m_s1ap; srslte::log_filter *m_s1ap_log; }; - } //namespace srsepc - -#endif //S1AP_MNGMT_PROC +#endif diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index c7c9e6057..539b1b245 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -80,6 +80,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { string mcc; string mnc; string mme_bind_addr; + string mme_apn; string spgw_bind_addr; string sgi_if_addr; string dns_addr; @@ -106,6 +107,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { ("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") + ("mme.apn", bpo::value(&mme_apn)->default_value(""), "Set Access Point Name (APN) for data services") ("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") @@ -207,6 +209,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->mme_args.s1ap_args.mme_apn = mme_apn; 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/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index ab383bf52..70769c9ef 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -118,7 +118,8 @@ mme_gtpc::send_create_session_request(uint64_t imsi, uint32_t mme_ue_s1ap_id, bo 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 - memcpy(cs_req->apn, "internet", sizeof("internet")); + 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; diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 921e5ff84..6e301b9ae 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -39,7 +39,8 @@ boost::mutex s1ap_instance_mutex; s1ap::s1ap(): m_s1mme(-1), m_next_mme_ue_s1ap_id(1), - m_next_m_tmsi(0xA000) + m_mme_gtpc(NULL), + m_pool(NULL) { } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index ab119041e..e49c3a05e 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -279,11 +279,13 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA if(*reply_flag == true) { - if(ue_emm_ctx != NULL) - { + 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); - //ue_emm_ctx->security_ctxt.dl_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_pool->deallocate(nas_msg); @@ -397,6 +399,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_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 -- 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 -- 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], @@ -419,7 +425,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_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)) { @@ -433,11 +442,11 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, //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); - + //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"); + m_s1ap_log->info("Downlink NAS: Sending Authentication Request\n"); + m_s1ap_log->console("Downlink NAS: Sending Authentication Request\n"); return true; } @@ -501,6 +510,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 + //Save attach request type + tmp_ue_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; //m_s1ap_log->console("EPS Bearer id: %d\n", eps_bearer_id); @@ -531,7 +543,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); //We do not know the IMSI of the UE yet - //This will be removed when the Identity request is received + //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); @@ -540,7 +552,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, return true; } 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 @@ -557,6 +569,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(); + //Save Attach type + ue_emm_ctx->attach_type = attach_req.eps_attach_type; //Create UE ECM context ue_ecm_ctx_t ue_ecm_ctx; @@ -584,12 +598,16 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, } else { - //NAS integrity failed. Re-start authentication process. + //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 } } else { m_s1ap_log->error("Found M-TMSI but could not find UE context\n"); + m_s1ap_log->console("Error: Found M-TMSI but could not find UE context\n"); return false; } } @@ -620,8 +638,9 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, { 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; + pack_service_reject(reply_buffer, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED, enb_ue_s1ap_id); + *reply_flag = true; + return true; } ue_emm_ctx_t *ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(it->second); @@ -629,8 +648,9 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, { 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; + 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); @@ -685,10 +705,10 @@ 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); - + //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->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ue_); + // m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ue_); } } else @@ -745,6 +765,7 @@ s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *na 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); *reply_flag = true; @@ -795,6 +816,7 @@ s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas { pack_esm_information_request(reply_buffer, ue_emm_ctx, ue_ecm_ctx); m_s1ap_log->console("Sending ESM information request\n"); + m_s1ap_log->info("Sending ESM information request\n"); *reply_flag = true; } else @@ -816,7 +838,7 @@ s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, u srslte::byte_buffer_t *esm_msg = m_pool->allocate(); LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT act_bearer; - m_s1ap_log->info_hex(nas_msg->msg, nas_msg->N_bytes, "NAS Attach complte"); + m_s1ap_log->info_hex(nas_msg->msg, nas_msg->N_bytes, "NAS Attach complete"); //Get NAS authentication response LIBLTE_ERROR_ENUM err = liblte_mme_unpack_attach_complete_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &attach_comp); @@ -832,7 +854,7 @@ s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, u } m_s1ap_log->console("Unpacked Attached Complete Message\n"); - m_s1ap_log->console("Unpacked Activavate Default EPS Bearer message. EPS Bearer id %d\n",act_bearer.eps_bearer_id); + 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) { @@ -867,6 +889,11 @@ s1ap_nas_transport::handle_esm_information_response(srslte::byte_buffer_t *nas_m 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); } + 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); + } //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. @@ -942,13 +969,6 @@ 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) { - /* - LIBLTE_ERROR_ENUM err = liblte_mme_unpack_tracking_area_update_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &tau_req); - if(err != LIBLTE_SUCCESS){ - m_s1ap_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]); - return false; - } - */ m_s1ap_log->console("Warning: Tracking Area Update Request messages not handled yet.\n"); m_s1ap_log->warning("Warning: Tracking Area Update Request messages not handled yet.\n"); //Setup initiating message @@ -970,7 +990,6 @@ 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; /* @@ -1245,8 +1264,8 @@ s1ap_nas_transport::pack_authentication_request(srslte::byte_buffer_t *reply_msg LIBLTE_ERROR_ENUM err = liblte_mme_pack_authentication_request_msg(&auth_req, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer); if(err != LIBLTE_SUCCESS) { - m_s1ap_log->error("Error packing Athentication Request\n"); - m_s1ap_log->console("Error packing Athentication Request\n"); + m_s1ap_log->error("Error packing Authentication Request\n"); + m_s1ap_log->console("Error packing Authentication Request\n"); return false; } @@ -1258,8 +1277,8 @@ s1ap_nas_transport::pack_authentication_request(srslte::byte_buffer_t *reply_msg err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_msg); if(err != LIBLTE_SUCCESS) { - m_s1ap_log->error("Error packing Athentication Request\n"); - m_s1ap_log->console("Error packing Athentication Request\n"); + m_s1ap_log->error("Error packing Authentication Request\n"); + m_s1ap_log->console("Error packing Authentication Request\n"); return false; } @@ -1296,8 +1315,8 @@ s1ap_nas_transport::pack_authentication_reject(srslte::byte_buffer_t *reply_msg, LIBLTE_ERROR_ENUM err = liblte_mme_pack_authentication_reject_msg(&auth_rej, (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"); + m_s1ap_log->error("Error packing Authentication Reject\n"); + m_s1ap_log->console("Error packing Authentication Reject\n"); return false; } @@ -1309,8 +1328,8 @@ s1ap_nas_transport::pack_authentication_reject(srslte::byte_buffer_t *reply_msg, 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: Athentication Reject\n"); - m_s1ap_log->console("Error packing Downlink NAS Transport: Athentication Reject\n"); + m_s1ap_log->error("Error packing Dw NAS Transport: Authentication Reject\n"); + m_s1ap_log->console("Error packing Downlink NAS Transport: Authentication Reject\n"); return false; } @@ -1399,7 +1418,7 @@ s1ap_nas_transport::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, 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"); + m_s1ap_log->console("Error packing Authentication Request\n"); return false; } @@ -1440,7 +1459,7 @@ s1ap_nas_transport::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_msg); if(err != LIBLTE_SUCCESS) { - m_s1ap_log->console("Error packing Athentication Request\n"); + m_s1ap_log->console("Error packing Authentication Request\n"); return false; } m_s1ap_log->debug_hex(reply_msg->msg, reply_msg->N_bytes, "Security Mode Command: "); @@ -1475,6 +1494,7 @@ s1ap_nas_transport::pack_esm_information_request(srslte::byte_buffer_t *reply_ms LIBLTE_MME_ESM_INFORMATION_REQUEST_MSG_STRUCT esm_info_req; esm_info_req.eps_bearer_id=0; esm_info_req.proc_transaction_id = ue_emm_ctx->procedure_transaction_id; + uint8_t sec_hdr_type=2; ue_emm_ctx->security_ctxt.dl_nas_count++; @@ -1506,8 +1526,8 @@ s1ap_nas_transport::pack_esm_information_request(srslte::byte_buffer_t *reply_ms 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: Athentication Reject\n"); - m_s1ap_log->console("Error packing Downlink NAS Transport: Athentication Reject\n"); + m_s1ap_log->error("Error packing Dw NAS Transport: Authentication Reject\n"); + m_s1ap_log->console("Error packing Downlink NAS Transport: Authentication Reject\n"); return false; } @@ -1545,10 +1565,8 @@ 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 = ue_emm_ctx->attach_type; - //Mandatory //FIXME: Set t3412 from config attach_accept.t3412.unit = LIBLTE_MME_GPRS_TIMER_UNIT_1_MINUTE; // GPRS 1 minute unit attach_accept.t3412.value = 30; // 30 minute periodic timer @@ -1611,10 +1629,9 @@ s1ap_nas_transport::pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *u act_def_eps_bearer_context_req.eps_qos.mbr_dl = 254; //FIXME act_def_eps_bearer_context_req.eps_qos.mbr_ul_ext = 250; //FIXME act_def_eps_bearer_context_req.eps_qos.mbr_dl_ext = 250; //FIXME check + //set apn - //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.apn.apn = m_s1ap->m_s1ap_args.mme_apn; act_def_eps_bearer_context_req.proc_transaction_id = ue_emm_ctx->procedure_transaction_id; //FIXME //Set DNS server @@ -1625,12 +1642,7 @@ s1ap_nas_transport::pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *u 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; @@ -1639,7 +1651,7 @@ s1ap_nas_transport::pack_attach_accept(ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *u 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 = 50; + act_def_eps_bearer_context_req.connectivity_type_present = false; uint8_t sec_hdr_type =2; ue_emm_ctx->security_ctxt.dl_nas_count++; @@ -1709,8 +1721,8 @@ s1ap_nas_transport::pack_identity_request(srslte::byte_buffer_t *reply_msg, uint 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: Athentication Reject\n"); - m_s1ap_log->console("Error packing Downlink NAS Transport: Athentication Reject\n"); + m_s1ap_log->error("Error packing Dw NAS Transport: Authentication Reject\n"); + m_s1ap_log->console("Error packing Downlink NAS Transport: Authentication Reject\n"); return false; } @@ -1796,6 +1808,59 @@ s1ap_nas_transport::pack_emm_information( ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte 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) 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); } 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..8e1a41478 100644 --- a/srsue/hdr/ue_base.h +++ b/srsue/hdr/ue_base.h @@ -126,6 +126,7 @@ typedef struct { usim_args_t usim; rrc_args_t rrc; std::string ue_category_str; + std::string apn; expert_args_t expert; }all_args_t; @@ -157,6 +158,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/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/main.cc b/srsue/src/main.cc index 1cac2092d..15f042411 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -82,6 +82,7 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { "UECapabilityInformation message. Default 0xe6041c00") ("rrc.ue_category", bpo::value(&args->ue_category_str)->default_value("4"), "UE Category (1 to 5)") + ("nas.apn", bpo::value(&args->apn)->default_value(""), "Set Access Point Name (APN) for data services") ("pcap.enable", bpo::value(&args->pcap.enable)->default_value(false), "Enable MAC packet captures for wireshark") ("pcap.filename", bpo::value(&args->pcap.filename)->default_value("ue.pcap"), "MAC layer capture filename") @@ -474,7 +475,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/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index b05a88205..ecd2cf241 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; } @@ -704,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; } } @@ -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++; diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 3a1dcbc98..88c9b54c8 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,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(); } } @@ -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; } diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 23175fa46..381cb52bf 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -190,7 +190,8 @@ bool ue::init(all_args_t *args_) pdcp.init(&rlc, &rrc, &gw, &pdcp_log, 0 /* RB_ID_SRB0 */, SECURITY_DIRECTION_UPLINK); usim.init(&args->usim, &usim_log); - nas.init(&usim, &rrc, &gw, &nas_log, 1 /* RB_ID_SRB1 */); + srslte_nas_config_t nas_cfg(1, args->apn); /* RB_ID_SRB1 */ + nas.init(&usim, &rrc, &gw, &nas_log, nas_cfg); gw.init(&pdcp, &nas, &gw_log, 3 /* RB_ID_DRB1 */); gw.set_netmask(args->expert.ip_netmask); @@ -278,6 +279,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; diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 8a05595c7..0a5b597e4 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,36 @@ 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 +802,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); } /******************************************************************************* @@ -893,7 +896,14 @@ void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg) { // Set the optional flags pdn_con_req.esm_info_transfer_flag_present = false; //FIXME: Check if this is needed - pdn_con_req.apn_present = false; + if (cfg.apn == "") { + pdn_con_req.apn_present = false; + } else { + pdn_con_req.apn_present = true; + LIBLTE_MME_ACCESS_POINT_NAME_STRUCT apn; + apn.apn = cfg.apn; + pdn_con_req.apn = apn; + } pdn_con_req.protocol_cnfg_opts_present = false; pdn_con_req.device_properties_present = false; 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(); } diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index b8cc43c2e..26a59f1be 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -109,6 +109,15 @@ imei = 353490069873319 #ue_category = 4 #feature_group = 0xe6041c00 +##################################################################### +# NAS configuration +# +# apn: Set Access Point Name (APN) +##################################################################### +[nas] +# apn = internetinternet + + [gui] enable = false