Resolving conflicts from merging next. Adding the functionality of echoing the attach type.

master
Pedro Alvarez 7 years ago
commit 5488609096

@ -173,6 +173,9 @@ public:
pool->deallocate(b); pool->deallocate(b);
b = NULL; b = NULL;
} }
void print_all_buffers() {
pool->print_all_buffers();
}
private: private:
buffer_pool<byte_buffer_t> *pool; buffer_pool<byte_buffer_t> *pool;
}; };

@ -96,6 +96,8 @@ static const char error_text[ERROR_N_ITEMS][20] = { "None",
"Can't start", "Can't start",
"Already started"}; "Already started"};
//#define ENABLE_TIMESTAMP
/****************************************************************************** /******************************************************************************
* Byte and Bit buffers * Byte and Bit buffers
* *
@ -147,33 +149,27 @@ public:
} }
long get_latency_us() long get_latency_us()
{ {
#ifdef ENABLE_TIMESTAMP
if(!timestamp_is_set) if(!timestamp_is_set)
return 0; return 0;
gettimeofday(&timestamp[2], NULL); gettimeofday(&timestamp[2], NULL);
get_time_interval(timestamp); get_time_interval(timestamp);
return timestamp[0].tv_usec; return timestamp[0].tv_usec;
#else
return 0;
#endif
} }
void set_timestamp() void set_timestamp()
{ {
#ifdef ENABLE_TIMESTAMP
gettimeofday(&timestamp[1], NULL); gettimeofday(&timestamp[1], NULL);
timestamp_is_set = true; timestamp_is_set = true;
#endif
} }
private: 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]; struct timeval timestamp[3];
bool timestamp_is_set; bool timestamp_is_set;
byte_buffer_t *next; byte_buffer_t *next;
@ -215,15 +211,21 @@ struct bit_buffer_t{
} }
long get_latency_us() long get_latency_us()
{ {
#ifdef ENABLE_TIMESTAMP
if(!timestamp_is_set) if(!timestamp_is_set)
return 0; return 0;
gettimeofday(&timestamp[2], NULL); gettimeofday(&timestamp[2], NULL);
return timestamp[0].tv_usec; return timestamp[0].tv_usec;
#else
return 0;
#endif
} }
void set_timestamp() void set_timestamp()
{ {
#ifdef ENABLE_TIMESTAMP
gettimeofday(&timestamp[1], NULL); gettimeofday(&timestamp[1], NULL);
timestamp_is_set = true; timestamp_is_set = true;
#endif
} }
private: private:

@ -30,6 +30,7 @@
#include "srslte/common/timers.h" #include "srslte/common/timers.h"
#include "srslte/common/security.h" #include "srslte/common/security.h"
#include "srslte/asn1/liblte_rrc.h" #include "srslte/asn1/liblte_rrc.h"
#include <string>
namespace srslte { namespace srslte {
@ -37,11 +38,13 @@ namespace srslte {
class srslte_nas_config_t class srslte_nas_config_t
{ {
public: public:
srslte_nas_config_t(uint32_t lcid_ = 0) srslte_nas_config_t(uint32_t lcid_ = 0, std::string apn_ = "")
:lcid(lcid_) :lcid(lcid_),
apn(apn_)
{} {}
uint32_t lcid; uint32_t lcid;
std::string apn;
}; };

@ -407,7 +407,7 @@ float srslte_cqi_to_coderate(uint32_t cqi) {
* Table III. * Table III.
*/ */
// From paper // 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 // 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}; //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};

@ -92,8 +92,12 @@ bool pdcp::is_drb_enabled(uint32_t lcid)
void pdcp::write_sdu(uint32_t lcid, byte_buffer_t *sdu) 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); 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) 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) 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); 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) void pdcp::write_pdu_bcch_bch(byte_buffer_t *sdu)

@ -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."); rlc_log->info_hex(payload, nof_bytes, "BCCH BCH message received.");
dl_tput_bytes[0] += nof_bytes; dl_tput_bytes[0] += nof_bytes;
byte_buffer_t *buf = pool_allocate; byte_buffer_t *buf = pool_allocate;
memcpy(buf->msg, payload, nof_bytes); if (buf) {
buf->N_bytes = nof_bytes; memcpy(buf->msg, payload, nof_bytes);
buf->set_timestamp(); buf->N_bytes = nof_bytes;
pdcp->write_pdu_bcch_bch(buf); 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) 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."); rlc_log->info_hex(payload, nof_bytes, "BCCH TXSCH message received.");
dl_tput_bytes[0] += nof_bytes; dl_tput_bytes[0] += nof_bytes;
byte_buffer_t *buf = pool_allocate; byte_buffer_t *buf = pool_allocate;
memcpy(buf->msg, payload, nof_bytes); if (buf) {
buf->N_bytes = nof_bytes; memcpy(buf->msg, payload, nof_bytes);
buf->set_timestamp(); buf->N_bytes = nof_bytes;
pdcp->write_pdu_bcch_dlsch(buf); 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) 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."); rlc_log->info_hex(payload, nof_bytes, "PCCH message received.");
dl_tput_bytes[0] += nof_bytes; dl_tput_bytes[0] += nof_bytes;
byte_buffer_t *buf = pool_allocate; byte_buffer_t *buf = pool_allocate;
memcpy(buf->msg, payload, nof_bytes); if (buf) {
buf->N_bytes = nof_bytes; memcpy(buf->msg, payload, nof_bytes);
buf->set_timestamp(); buf->N_bytes = nof_bytes;
pdcp->write_pdu_pcch(buf); 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) bool rlc::valid_lcid(uint32_t lcid)
{ {
if(lcid >= SRSLTE_N_RADIO_BEARERS) { if(lcid >= SRSLTE_N_RADIO_BEARERS) {
rlc_log->warning("Invalid LCID=%d\n", lcid);
return false; return false;
} else if(!rlc_array[lcid].active()) { } else if(!rlc_array[lcid].active()) {
return false; return false;

@ -11,6 +11,7 @@
# mcc: Mobile Country Code # mcc: Mobile Country Code
# mnc: Mobile Network Code # mnc: Mobile Network Code
# mme_bindx_addr: IP subnet to listen for eNB S1 connnections # mme_bindx_addr: IP subnet to listen for eNB S1 connnections
# apn: Set Access Point Name (APN)
# #
##################################################################### #####################################################################
[mme] [mme]
@ -20,6 +21,7 @@ tac = 0x0007
mcc = 001 mcc = 001
mnc = 01 mnc = 01
mme_bind_addr = 127.0.1.100 mme_bind_addr = 127.0.1.100
apn = test123
##################################################################### #####################################################################
# HSS configuration # HSS configuration

@ -91,6 +91,7 @@ typedef struct{
std::string mme_bind_addr; std::string mme_bind_addr;
std::string mme_name; std::string mme_name;
std::string dns_addr; std::string dns_addr;
std::string mme_apn;
} s1ap_args_t; } s1ap_args_t;
typedef struct{ typedef struct{
@ -138,6 +139,7 @@ typedef struct{
uint8_t procedure_transaction_id; uint8_t procedure_transaction_id;
emm_state_t emm_state; emm_state_t emm_state;
uint32_t mme_ue_s1ap_id; uint32_t mme_ue_s1ap_id;
uint8_t attach_type;
} ue_emm_ctx_t; } ue_emm_ctx_t;
typedef struct{ typedef struct{
@ -162,6 +164,7 @@ typedef struct{
erab_ctx_t erabs_ctx[MAX_ERABS_PER_UE]; erab_ctx_t erabs_ctx[MAX_ERABS_PER_UE];
bool eit; bool eit;
uint8_t procedure_transaction_id; uint8_t procedure_transaction_id;
uint8_t attach_type;
} ue_ctx_t; } ue_ctx_t;
}//namespace }//namespace
#endif #endif

@ -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_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_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_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); 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; hss_interface_s1ap* m_hss;
mme_gtpc* m_mme_gtpc; mme_gtpc* m_mme_gtpc;
}; };
} //namespace srsepc } //namespace srsepc
#endif //S1AP_NAS_TRANSPORT #endif //S1AP_NAS_TRANSPORT

@ -54,7 +54,5 @@ private:
s1ap* m_s1ap; s1ap* m_s1ap;
srslte::log_filter *m_s1ap_log; srslte::log_filter *m_s1ap_log;
}; };
} //namespace srsepc } //namespace srsepc
#endif
#endif //S1AP_MNGMT_PROC

@ -80,6 +80,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) {
string mcc; string mcc;
string mnc; string mnc;
string mme_bind_addr; string mme_bind_addr;
string mme_apn;
string spgw_bind_addr; string spgw_bind_addr;
string sgi_if_addr; string sgi_if_addr;
string dns_addr; string dns_addr;
@ -106,6 +107,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) {
("mme.mnc", bpo::value<string>(&mnc)->default_value("01"), "Mobile Network Code") ("mme.mnc", bpo::value<string>(&mnc)->default_value("01"), "Mobile Network Code")
("mme.mme_bind_addr", bpo::value<string>(&mme_bind_addr)->default_value("127.0.0.1"),"IP address of MME for S1 connnection") ("mme.mme_bind_addr", bpo::value<string>(&mme_bind_addr)->default_value("127.0.0.1"),"IP address of MME for S1 connnection")
("mme.dns_addr", bpo::value<string>(&dns_addr)->default_value("8.8.8.8"),"IP address of the DNS server for the UEs") ("mme.dns_addr", bpo::value<string>(&dns_addr)->default_value("8.8.8.8"),"IP address of the DNS server for the UEs")
("mme.apn", bpo::value<string>(&mme_apn)->default_value(""), "Set Access Point Name (APN) for data services")
("hss.db_file", bpo::value<string>(&hss_db_file)->default_value("ue_db.csv"),".csv file that stores UE's keys") ("hss.db_file", bpo::value<string>(&hss_db_file)->default_value("ue_db.csv"),".csv file that stores UE's keys")
("hss.auth_algo", bpo::value<string>(&hss_auth_algo)->default_value("milenage"),"HSS uthentication algorithm.") ("hss.auth_algo", bpo::value<string>(&hss_auth_algo)->default_value("milenage"),"HSS uthentication algorithm.")
("spgw.gtpu_bind_addr", bpo::value<string>(&spgw_bind_addr)->default_value("127.0.0.1"),"IP address of SP-GW for the S1-U connection") ("spgw.gtpu_bind_addr", bpo::value<string>(&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_bind_addr = mme_bind_addr;
args->mme_args.s1ap_args.mme_name = mme_name; args->mme_args.s1ap_args.mme_name = mme_name;
args->mme_args.s1ap_args.dns_addr = dns_addr; 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.gtpu_bind_addr = spgw_bind_addr;
args->spgw_args.sgi_if_addr = sgi_if_addr; args->spgw_args.sgi_if_addr = sgi_if_addr;
args->hss_args.db_file = hss_db_file; args->hss_args.db_file = hss_db_file;

@ -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 -- IMSI: %015lu \n", imsi);
m_mme_gtpc_log->console("Creating Session Response -- MME control TEID: %lu \n", cs_req->sender_f_teid.teid); m_mme_gtpc_log->console("Creating Session Response -- MME control TEID: %lu \n", cs_req->sender_f_teid.teid);
// APN // 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 // RAT Type
//cs_req->rat_type = srslte::GTPC_RAT_TYPE::EUTRAN; //cs_req->rat_type = srslte::GTPC_RAT_TYPE::EUTRAN;

@ -39,7 +39,8 @@ boost::mutex s1ap_instance_mutex;
s1ap::s1ap(): s1ap::s1ap():
m_s1mme(-1), m_s1mme(-1),
m_next_mme_ue_s1ap_id(1), m_next_mme_ue_s1ap_id(1),
m_next_m_tmsi(0xA000) m_mme_gtpc(NULL),
m_pool(NULL)
{ {
} }

@ -279,11 +279,13 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA
if(*reply_flag == true) 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->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->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); 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->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->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 -- 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", 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[0],
attach_req.ue_network_cap.eea[1], attach_req.ue_network_cap.eea[1],
@ -420,6 +426,9 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_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 -- 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("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 //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(ue_emm_ctx.imsi, ue_emm_ctx.security_ctxt.k_asme, autn, rand, ue_emm_ctx.security_ctxt.xres))
{ {
@ -436,8 +445,8 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id,
//Send reply to eNB //Send reply to eNB
*reply_flag = true; *reply_flag = true;
m_s1ap_log->info("Downlink NAS: Sending Athentication Request\n"); m_s1ap_log->info("Downlink NAS: Sending Authentication Request\n");
m_s1ap_log->console("Downlink NAS: Sending Athentication Request\n"); m_s1ap_log->console("Downlink NAS: Sending Authentication Request\n");
return true; 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 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 //Save whether ESM information transfer is necessary
ue_ecm_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); //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); m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx);
//We do not know the IMSI of the UE yet //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; 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); m_s1ap->store_tmp_ue_emm_ctx(tmp_ue_emm_ctx);
@ -557,6 +569,8 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id,
//Create new MME UE S1AP Identity //Create new MME UE S1AP Identity
ue_emm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); 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 //Create UE ECM context
ue_ecm_ctx_t ue_ecm_ctx; ue_ecm_ctx_t ue_ecm_ctx;
@ -585,11 +599,15 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id,
else 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 else
{ {
m_s1ap_log->error("Found M-TMSI but could not find UE context\n"); 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; 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->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); m_s1ap_log->error("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi);
//FIXME send service reject pack_service_reject(reply_buffer, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED, enb_ue_s1ap_id);
return false; *reply_flag = true;
return true;
} }
ue_emm_ctx_t *ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(it->second); 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->console("Could not find UE security context\n");
m_s1ap_log->error("Could not find UE security context\n"); m_s1ap_log->error("Could not find UE security context\n");
//FIXME send service reject pack_service_reject(reply_buffer, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED, enb_ue_s1ap_id);
return false; *reply_flag = true;
return true;
} }
ue_emm_ctx->security_ctxt.ul_nas_count++; ue_emm_ctx->security_ctxt.ul_nas_count++;
mac_valid = short_integrity_check(ue_emm_ctx,nas_msg); 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 //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); 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_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, 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.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 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->console("UE Authentication Rejected.\n");
m_s1ap_log->warning("UE Authentication Rejected.\n"); m_s1ap_log->warning("UE Authentication Rejected.\n");
//Send back Athentication Reject //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, ue_ecm_ctx->enb_ue_s1ap_id, ue_ecm_ctx->mme_ue_s1ap_id);
*reply_flag = true; *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); pack_esm_information_request(reply_buffer, ue_emm_ctx, ue_ecm_ctx);
m_s1ap_log->console("Sending ESM information request\n"); m_s1ap_log->console("Sending ESM information request\n");
m_s1ap_log->info("Sending ESM information request\n");
*reply_flag = true; *reply_flag = true;
} }
else 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(); srslte::byte_buffer_t *esm_msg = m_pool->allocate();
LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT act_bearer; 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 //Get NAS authentication response
LIBLTE_ERROR_ENUM err = liblte_mme_unpack_attach_complete_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &attach_comp); 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 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; //ue_ctx->erabs_ctx[act_bearer->eps_bearer_id].enb_fteid;
if(act_bearer.eps_bearer_id < 5 || act_bearer.eps_bearer_id > 15) 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->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->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. //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. //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) 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->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"); m_s1ap_log->warning("Warning: Tracking Area Update Request messages not handled yet.\n");
//Setup initiating message //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->HandoverRestrictionList_present=false;
dw_nas->SubscriberProfileIDforRFP_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; 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); LIBLTE_ERROR_ENUM err = liblte_mme_pack_authentication_request_msg(&auth_req, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer);
if(err != LIBLTE_SUCCESS) if(err != LIBLTE_SUCCESS)
{ {
m_s1ap_log->error("Error packing Athentication Request\n"); m_s1ap_log->error("Error packing Authentication Request\n");
m_s1ap_log->console("Error packing Athentication Request\n"); m_s1ap_log->console("Error packing Authentication Request\n");
return false; 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); err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_msg);
if(err != LIBLTE_SUCCESS) if(err != LIBLTE_SUCCESS)
{ {
m_s1ap_log->error("Error packing Athentication Request\n"); m_s1ap_log->error("Error packing Authentication Request\n");
m_s1ap_log->console("Error packing Athentication Request\n"); m_s1ap_log->console("Error packing Authentication Request\n");
return false; 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); LIBLTE_ERROR_ENUM err = liblte_mme_pack_authentication_reject_msg(&auth_rej, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer);
if(err != LIBLTE_SUCCESS) if(err != LIBLTE_SUCCESS)
{ {
m_s1ap_log->error("Error packing Athentication Reject\n"); m_s1ap_log->error("Error packing Authentication Reject\n");
m_s1ap_log->console("Error packing Athentication Reject\n"); m_s1ap_log->console("Error packing Authentication Reject\n");
return false; 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); err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_msg);
if(err != LIBLTE_SUCCESS) if(err != LIBLTE_SUCCESS)
{ {
m_s1ap_log->error("Error packing Dw 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: Athentication Reject\n"); m_s1ap_log->console("Error packing Downlink NAS Transport: Authentication Reject\n");
return false; 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); 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) if(err != LIBLTE_SUCCESS)
{ {
m_s1ap_log->console("Error packing Athentication Request\n"); m_s1ap_log->console("Error packing Authentication Request\n");
return false; 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); err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_msg);
if(err != LIBLTE_SUCCESS) if(err != LIBLTE_SUCCESS)
{ {
m_s1ap_log->console("Error packing Athentication Request\n"); m_s1ap_log->console("Error packing Authentication Request\n");
return false; return false;
} }
m_s1ap_log->debug_hex(reply_msg->msg, reply_msg->N_bytes, "Security Mode Command: "); 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; LIBLTE_MME_ESM_INFORMATION_REQUEST_MSG_STRUCT esm_info_req;
esm_info_req.eps_bearer_id=0; esm_info_req.eps_bearer_id=0;
esm_info_req.proc_transaction_id = ue_emm_ctx->procedure_transaction_id; esm_info_req.proc_transaction_id = ue_emm_ctx->procedure_transaction_id;
uint8_t sec_hdr_type=2; uint8_t sec_hdr_type=2;
ue_emm_ctx->security_ctxt.dl_nas_count++; 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); err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_msg);
if(err != LIBLTE_SUCCESS) if(err != LIBLTE_SUCCESS)
{ {
m_s1ap_log->error("Error packing Dw 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: Athentication Reject\n"); m_s1ap_log->console("Error packing Downlink NAS Transport: Authentication Reject\n");
return false; 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
//attach_accept.eps_attach_result = LIBLTE_MME_EPS_ATTACH_RESULT_EPS_ONLY; attach_accept.eps_attach_result = ue_emm_ctx->attach_type;
attach_accept.eps_attach_result = LIBLTE_MME_EPS_ATTACH_RESULT_COMBINED_EPS_IMSI_ATTACH;
//Mandatory
//FIXME: Set t3412 from config //FIXME: Set t3412 from config
attach_accept.t3412.unit = LIBLTE_MME_GPRS_TIMER_UNIT_1_MINUTE; // GPRS 1 minute unit attach_accept.t3412.unit = LIBLTE_MME_GPRS_TIMER_UNIT_1_MINUTE; // GPRS 1 minute unit
attach_accept.t3412.value = 30; // 30 minute periodic timer 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_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_ul_ext = 250; //FIXME
act_def_eps_bearer_context_req.eps_qos.mbr_dl_ext = 250; //FIXME check act_def_eps_bearer_context_req.eps_qos.mbr_dl_ext = 250; //FIXME check
//set apn //set apn
//act_def_eps_bearer_context_req.apn act_def_eps_bearer_context_req.apn.apn = m_s1ap->m_s1ap_args.mme_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_emm_ctx->procedure_transaction_id; //FIXME act_def_eps_bearer_context_req.proc_transaction_id = ue_emm_ctx->procedure_transaction_id; //FIXME
//Set DNS server //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; struct sockaddr_in dns_addr;
inet_pton(AF_INET, m_s1ap->m_s1ap_args.dns_addr.c_str(), &(dns_addr.sin_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); 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 //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.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.packet_flow_id_present = false;
act_def_eps_bearer_context_req.apn_ambr_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 = 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; uint8_t sec_hdr_type =2;
ue_emm_ctx->security_ctxt.dl_nas_count++; 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); err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_msg);
if(err != LIBLTE_SUCCESS) if(err != LIBLTE_SUCCESS)
{ {
m_s1ap_log->error("Error packing Dw 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: Athentication Reject\n"); m_s1ap_log->console("Error packing Downlink NAS Transport: Authentication Reject\n");
return false; return false;
} }
@ -1796,6 +1808,59 @@ s1ap_nas_transport::pack_emm_information( ue_ecm_ctx_t *ue_ecm_ctx, srslte::byte
return true; 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*/ /*Helper functions*/
void void
s1ap_nas_transport::log_unhandled_attach_request_ies(const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT *attach_req) s1ap_nas_transport::log_unhandled_attach_request_ies(const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT *attach_req)

@ -226,7 +226,9 @@ private:
is_first_tb = true; is_first_tb = true;
ack = false; ack = false;
if (payload_buffer_ptr) { 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; payload_buffer_ptr = NULL;
} }
bzero(&cur_grant, sizeof(Tgrant)); bzero(&cur_grant, sizeof(Tgrant));
@ -342,7 +344,7 @@ private:
harq_entity->nof_pkts++); harq_entity->nof_pkts++);
} }
} }
} else { } else if (pid != HARQ_BCCH_PID) {
harq_entity->demux_unit->deallocate(payload_buffer_ptr); harq_entity->demux_unit->deallocate(payload_buffer_ptr);
} }

@ -72,6 +72,8 @@ public:
bool is_attached(); bool is_attached();
void start_plot(); void start_plot();
void print_pool();
static void rf_msg(srslte_rf_error_t error); static void rf_msg(srslte_rf_error_t error);
// UE metrics interface // UE metrics interface

@ -126,6 +126,7 @@ typedef struct {
usim_args_t usim; usim_args_t usim;
rrc_args_t rrc; rrc_args_t rrc;
std::string ue_category_str; std::string ue_category_str;
std::string apn;
expert_args_t expert; expert_args_t expert;
}all_args_t; }all_args_t;
@ -157,6 +158,8 @@ public:
virtual bool is_attached() = 0; virtual bool is_attached() = 0;
virtual void start_plot() = 0; virtual void start_plot() = 0;
virtual void print_pool() = 0;
virtual void radio_overflow() = 0; virtual void radio_overflow() = 0;
void handle_rf_msg(srslte_rf_error_t error); void handle_rf_msg(srslte_rf_error_t error);

@ -295,9 +295,9 @@ private:
LIBLTE_RRC_DL_CCCH_MSG_STRUCT dl_ccch_msg; LIBLTE_RRC_DL_CCCH_MSG_STRUCT dl_ccch_msg;
LIBLTE_RRC_DL_DCCH_MSG_STRUCT dl_dcch_msg; LIBLTE_RRC_DL_DCCH_MSG_STRUCT dl_dcch_msg;
byte_buffer_t* byte_align_and_pack(byte_buffer_t *pdu = NULL); byte_buffer_t* byte_align_and_pack();
void send_ul_ccch_msg(byte_buffer_t *pdu = NULL); void send_ul_ccch_msg();
void send_ul_dcch_msg(byte_buffer_t *pdu = NULL); void send_ul_dcch_msg();
srslte::bit_buffer_t bit_buf; srslte::bit_buffer_t bit_buf;
pthread_mutex_t mutex; 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_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause, uint16_t crnti);
void send_con_restablish_complete(); void send_con_restablish_complete();
void send_con_setup_complete(byte_buffer_t *nas_msg); void send_con_setup_complete(byte_buffer_t *nas_msg);
void send_ul_info_transfer(uint32_t lcid, byte_buffer_t *sdu); void send_ul_info_transfer(byte_buffer_t *nas_msg);
void send_security_mode_complete(uint32_t lcid, byte_buffer_t *pdu); void send_security_mode_complete();
void send_rrc_con_reconfig_complete(byte_buffer_t *pdu); void send_rrc_con_reconfig_complete();
void send_rrc_ue_cap_info(byte_buffer_t *pdu); void send_rrc_ue_cap_info();
// Parsers // Parsers
void parse_dl_ccch(byte_buffer_t *pdu); 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 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_setup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *setup);
void handle_con_reest(LIBLTE_RRC_CONNECTION_REESTABLISHMENT_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_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg);
void add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg); void add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg);
void release_drb(uint8_t lcid); void release_drb(uint8_t lcid);

@ -82,6 +82,7 @@ void parse_args(all_args_t *args, int argc, char *argv[]) {
"UECapabilityInformation message. Default 0xe6041c00") "UECapabilityInformation message. Default 0xe6041c00")
("rrc.ue_category", bpo::value<string>(&args->ue_category_str)->default_value("4"), "UE Category (1 to 5)") ("rrc.ue_category", bpo::value<string>(&args->ue_category_str)->default_value("4"), "UE Category (1 to 5)")
("nas.apn", bpo::value<string>(&args->apn)->default_value(""), "Set Access Point Name (APN) for data services")
("pcap.enable", bpo::value<bool>(&args->pcap.enable)->default_value(false), "Enable MAC packet captures for wireshark") ("pcap.enable", bpo::value<bool>(&args->pcap.enable)->default_value(false), "Enable MAC packet captures for wireshark")
("pcap.filename", bpo::value<string>(&args->pcap.filename)->default_value("ue.pcap"), "MAC layer capture filename") ("pcap.filename", bpo::value<string>(&args->pcap.filename)->default_value("ue.pcap"), "MAC layer capture filename")
@ -474,7 +475,8 @@ int main(int argc, char *argv[])
plot_started = true; plot_started = true;
} }
} }
sleep(1); ue->print_pool();
sleep(10);
} }
pthread_cancel(input); pthread_cancel(input);
metricshub.stop(); metricshub.stop();

@ -142,8 +142,8 @@ void phch_recv::reset()
void phch_recv::radio_error() void phch_recv::radio_error()
{ {
log_h->error("SYNC: Receiving from radio.\n"); log_h->error("SYNC: Receiving from radio.\n");
phy_state = CELL_SEARCH;
reset(); reset();
phy_state = CELL_SEARCH;
// Need to find a method to effectively reset radio, reloading the driver does not work // Need to find a method to effectively reset radio, reloading the driver does not work
radio_h->reset(); radio_h->reset();
} }
@ -257,20 +257,20 @@ void phch_recv::force_freq(float dl_freq, float ul_freq) {
void phch_recv::reset_sync() { void phch_recv::reset_sync() {
Info("SYNC: Reset. Going to Cell Select\n");
sfn_p.reset(); sfn_p.reset();
search_p.reset(); search_p.reset();
measure_p.reset(); measure_p.reset();
srslte_ue_sync_reset(&ue_sync); srslte_ue_sync_reset(&ue_sync);
Info("----- PHY RESET----\n");
phy_state = CELL_SELECT; phy_state = CELL_SELECT;
} }
void phch_recv::cell_search_inc() void phch_recv::cell_search_inc()
{ {
Info("cell_search_inc, cur_idx=%d, size=%d\n", cur_earfcn_index, earfcn.size());
cur_earfcn_index++; cur_earfcn_index++;
if (cur_earfcn_index >= 0) { if (cur_earfcn_index >= 0) {
if (cur_earfcn_index >= (int) earfcn.size()) { if (cur_earfcn_index >= (int) earfcn.size()) {
Info("SYNC: Cell Search finished. Going to IDLE\n");
cur_earfcn_index = 0; cur_earfcn_index = 0;
phy_state = IDLE; phy_state = IDLE;
rrc->earfcn_end(); 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 */ /* 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_earfcn = earfcn;
new_cell = cell; new_cell = cell;
phy_state = CELL_RESELECT; phy_state = CELL_RESELECT;
@ -359,7 +360,6 @@ void phch_recv::cell_reselect()
uint32_t earfcn = new_earfcn; uint32_t earfcn = new_earfcn;
srslte_cell_t cell = new_cell; srslte_cell_t cell = new_cell;
Info("Reset from cell_reselect\n");
reset_sync(); reset_sync();
// If we are already in the new cell, just resynchronize // If we are already in the new cell, just resynchronize
@ -529,11 +529,12 @@ void phch_recv::run_thread()
{ {
case search::CELL_FOUND: case search::CELL_FOUND:
if (!srslte_cell_isvalid(&cell)) { if (!srslte_cell_isvalid(&cell)) {
Error("SYNC: Detected invalid cell\n"); Error("SYNC: Detected invalid cell. Going to IDLE\n");
phy_state = IDLE; phy_state = IDLE;
break; break;
} }
if (set_cell()) { if (set_cell()) {
Info("SYNC: Setting sampling rate and going to Cell Select\n");
set_sampling_rate(); set_sampling_rate();
phy_state = CELL_SELECT; phy_state = CELL_SELECT;
} }
@ -704,23 +705,23 @@ void phch_recv::run_thread()
} }
void phch_recv::in_sync() { void phch_recv::in_sync() {
out_of_sync_cnt = 0;
in_sync_cnt++; in_sync_cnt++;
// Send RRC in-sync signal after 100 ms consecutive subframes // Send RRC in-sync signal after 100 ms consecutive subframes
if (in_sync_cnt == NOF_IN_SYNC_SF) { if (in_sync_cnt == NOF_IN_SYNC_SF) {
rrc->in_sync(); rrc->in_sync();
in_sync_cnt = 0; in_sync_cnt = 0;
out_of_sync_cnt = 0;
} }
} }
// Out of sync called by worker or phch_recv every 1 or 5 ms // Out of sync called by worker or phch_recv every 1 or 5 ms
void phch_recv::out_of_sync() { void phch_recv::out_of_sync() {
in_sync_cnt = 0;
// Send RRC out-of-sync signal after 200 ms consecutive subframes // Send RRC out-of-sync signal after 200 ms consecutive subframes
out_of_sync_cnt++; out_of_sync_cnt++;
if (out_of_sync_cnt >= NOF_OUT_OF_SYNC_SF) { if (out_of_sync_cnt >= NOF_OUT_OF_SYNC_SF) {
rrc->out_of_sync(); rrc->out_of_sync();
out_of_sync_cnt = 0; 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 { } else {
Info("SYNC: PSS/SSS not found...\n"); Debug("SYNC: PSS/SSS not found...\n");
} }
cnt++; cnt++;

@ -397,7 +397,9 @@ void phch_worker::work_imp()
if (!dl_action.generate_ack_callback) { if (!dl_action.generate_ack_callback) {
if (dl_mac_grant.rnti_type == SRSLTE_RNTI_PCH && dl_action.decode_enabled[0]) { 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) { } else if (!rar_delivered) {
for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) {
if (dl_action.decode_enabled[tb]) { if (dl_action.decode_enabled[tb]) {
@ -410,13 +412,13 @@ void phch_worker::work_imp()
update_measurements(); update_measurements();
if (chest_ok) { 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", 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(); chest_loop->in_sync();
} else { } else {
log_h->warning("SNR=%.1f dB RSRP=%.1f dBm, sync=out-of-sync from channel estimator\n", 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(); chest_loop->out_of_sync();
} }
} }
@ -520,10 +522,15 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant)
srslte_dci_msg_t dci_msg; srslte_dci_msg_t dci_msg;
srslte_ra_dl_dci_t dci_unpacked; 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, 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) { dl_rnti, type, &dci_msg) != 1) {
if (type == SRSLTE_RNTI_RAR) {
Info("RAR not found\n");
}
return false; return false;
} }

@ -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); pdcp.init(&rlc, &rrc, &gw, &pdcp_log, 0 /* RB_ID_SRB0 */, SECURITY_DIRECTION_UPLINK);
usim.init(&args->usim, &usim_log); 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.init(&pdcp, &nas, &gw_log, 3 /* RB_ID_DRB1 */);
gw.set_netmask(args->expert.ip_netmask); gw.set_netmask(args->expert.ip_netmask);
@ -278,6 +279,10 @@ void ue::start_plot() {
phy.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) bool ue::get_metrics(ue_metrics_t &m)
{ {
m.rf = rf_metrics; m.rf = rf_metrics;

@ -222,7 +222,7 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) {
default: default:
nas_log->error("Not handling NAS message with SEC_HDR_TYPE=%02X\n", sec_hdr_type); nas_log->error("Not handling NAS message with SEC_HDR_TYPE=%02X\n", sec_hdr_type);
pool->deallocate(pdu); pool->deallocate(pdu);
break; return;
} }
// Write NAS pcap // Write NAS pcap
@ -266,7 +266,7 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) {
default: default:
nas_log->error("Not handling NAS message with MSG_TYPE=%02X\n", msg_type); nas_log->error("Not handling NAS message with MSG_TYPE=%02X\n", msg_type);
pool->deallocate(pdu); 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; 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, liblte_mme_pack_activate_default_eps_bearer_context_accept_msg(&act_def_eps_bearer_context_accept,
&attach_complete.esm_msg); &attach_complete.esm_msg);
pdu->reset();
liblte_mme_pack_attach_complete_msg(&attach_complete, liblte_mme_pack_attach_complete_msg(&attach_complete,
LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED,
ctxt.tx_count, ctxt.tx_count,
@ -762,36 +764,36 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu)
} }
// Send response // Send response
byte_buffer_t *sdu = pool_allocate; pdu->reset();
liblte_mme_pack_security_mode_complete_msg(&sec_mode_comp, liblte_mme_pack_security_mode_complete_msg(&sec_mode_comp,
LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT,
ctxt.tx_count, ctxt.tx_count,
(LIBLTE_BYTE_MSG_STRUCT *) sdu); (LIBLTE_BYTE_MSG_STRUCT *) pdu);
if(pcap != NULL) { 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], integrity_generate(&k_nas_int[16],
ctxt.tx_count, ctxt.tx_count,
SECURITY_DIRECTION_UPLINK, SECURITY_DIRECTION_UPLINK,
&sdu->msg[5], &pdu->msg[5],
sdu->N_bytes - 5, pdu->N_bytes - 5,
&sdu->msg[1]); &pdu->msg[1]);
nas_log->info("Sending Security Mode Complete nas_current_ctxt.tx_count=%d, RB=%s\n", nas_log->info("Sending Security Mode Complete nas_current_ctxt.tx_count=%d, RB=%s\n",
ctxt.tx_count, ctxt.tx_count,
rrc->get_rb_name(lcid).c_str()); rrc->get_rb_name(lcid).c_str());
rrc->write_sdu(lcid, sdu); rrc->write_sdu(lcid, pdu);
ctxt.tx_count++; ctxt.tx_count++;
pool->deallocate(pdu);
} }
void nas::parse_service_reject(uint32_t lcid, byte_buffer_t *pdu) { void nas::parse_service_reject(uint32_t lcid, byte_buffer_t *pdu) {
nas_log->error("TODO:parse_service_reject\n"); nas_log->error("TODO:parse_service_reject\n");
pool->deallocate(pdu);
} }
void nas::parse_esm_information_request(uint32_t lcid, byte_buffer_t *pdu) { void nas::parse_esm_information_request(uint32_t lcid, byte_buffer_t *pdu) {
nas_log->error("TODO:parse_esm_information_request\n"); nas_log->error("TODO:parse_esm_information_request\n");
pool->deallocate(pdu);
} }
void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *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->info("Received EMM Information: %s\n", str.c_str());
nas_log->console("%s\n", str.c_str()); nas_log->console("%s\n", str.c_str());
ctxt.rx_count++; 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 // Set the optional flags
pdn_con_req.esm_info_transfer_flag_present = false; //FIXME: Check if this is needed 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.protocol_cnfg_opts_present = false;
pdn_con_req.device_properties_present = false; pdn_con_req.device_properties_present = false;

@ -1070,34 +1070,36 @@ void rrc::send_con_setup_complete(byte_buffer_t *nas_msg) {
send_ul_dcch_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"); rrc_log->debug("Preparing RX Info Transfer\n");
// Prepare RX INFO packet // Prepare RX INFO packet
ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_UL_INFO_TRANSFER; 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; 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); 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 = sdu->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"); 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_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_SECURITY_MODE_COMPLETE;
ul_dcch_msg.msg.security_mode_complete.rrc_transaction_id = transaction_id; 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"); 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_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_RRC_CON_RECONFIG_COMPLETE;
ul_dcch_msg.msg.rrc_con_reconfig_complete.rrc_transaction_id = transaction_id; 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() { 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); 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); 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; 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); 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, void rrc::handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *reconfig) {
byte_buffer_t *pdu) {
uint32_t i; uint32_t i;
if (reconfig->mob_ctrl_info_present) { if (reconfig->mob_ctrl_info_present) {
if (reconfig->mob_ctrl_info.target_pci == phy->get_current_pci()) { if (reconfig->mob_ctrl_info.target_pci == phy->get_current_pci()) {
rrc_log->warning("Received HO command to own cell\n"); rrc_log->warning("Received HO command to own cell\n");
send_rrc_con_reconfig_complete(pdu); send_rrc_con_reconfig_complete();
} else { } else {
rrc_log->info("Received HO command to target PCell=%d\n", reconfig->mob_ctrl_info.target_pci); 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", 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); measurements.parse_meas_config(&reconfig->meas_cnfg);
} }
send_rrc_con_reconfig_complete(pdu); send_rrc_con_reconfig_complete();
byte_buffer_t *nas_sdu; byte_buffer_t *nas_sdu;
for (i = 0; i < reconfig->N_ded_info_nas; i++) { 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) { void rrc::write_pdu_bcch_bch(byte_buffer_t *pdu) {
pool->deallocate(pdu);
if (state == RRC_STATE_PLMN_SELECTION) { if (state == RRC_STATE_PLMN_SELECTION) {
// Do we need to do something with BCH? // Do we need to do something with BCH?
rrc_log->info_hex(pdu->msg, pdu->N_bytes, "BCCH BCH message received."); rrc_log->info_hex(pdu->msg, pdu->N_bytes, "BCCH BCH message received.");
pool->deallocate(pdu);
} else { } else {
rrc_log->warning("Received BCCH BCH in incorrect state\n"); 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 // Byte align and pack the message bits for PDCP
if ((bit_buf.N_bits % 8) != 0) { 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 // Reset and reuse sdu buffer if provided
byte_buffer_t *pdcp_buf = pdu; byte_buffer_t *pdcp_buf = pool_allocate;
if (pdcp_buf) { 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); 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->N_bytes = bit_buf.N_bits / 8;
pdcp_buf->set_timestamp(); pdcp_buf->set_timestamp();
@ -1551,10 +1545,10 @@ byte_buffer_t* rrc::byte_align_and_pack(byte_buffer_t *pdu)
return pdcp_buf; 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); 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) { if (pdu) {
// Set UE contention resolution ID in MAC // Set UE contention resolution ID in MAC
uint64_t uecri = 0; 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); liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf);
byte_buffer_t *pdu = byte_align_and_pack();
pdu = byte_align_and_pack(pdu);
if (pdu) { if (pdu) {
rrc_log->info("Sending %s\n", liblte_rrc_ul_dcch_msg_type_text[ul_dcch_msg.msg_type]); 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); 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); send_con_setup_complete(sdu);
break; break;
case RRC_STATE_CONNECTED: case RRC_STATE_CONNECTED:
send_ul_info_transfer(lcid, sdu); send_ul_info_transfer(sdu);
break; break;
default: default:
rrc_log->error("SDU received from NAS while RRC state = %s\n", rrc_state_text[state]); 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(), get_rb_name(lcid).c_str(),
liblte_rrc_dl_dcch_msg_type_text[dl_dcch_msg.msg_type]); liblte_rrc_dl_dcch_msg_type_text[dl_dcch_msg.msg_type]);
// Reset and reuse pdu buffer if possible pool->deallocate(pdu);
pdu->reset();
switch (dl_dcch_msg.msg_type) { switch (dl_dcch_msg.msg_type) {
case LIBLTE_RRC_DL_DCCH_MSG_TYPE_DL_INFO_TRANSFER: 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, memcpy(pdu->msg, dl_dcch_msg.msg.dl_info_transfer.dedicated_info.msg,
dl_dcch_msg.msg.dl_info_transfer.dedicated_info.N_bytes); 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; 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 // Configure PDCP for security
pdcp->config_security(lcid, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); pdcp->config_security(lcid, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo);
pdcp->enable_integrity(lcid); pdcp->enable_integrity(lcid);
send_security_mode_complete(lcid, pdu); send_security_mode_complete();
pdcp->enable_encryption(lcid); pdcp->enable_encryption(lcid);
break; break;
case LIBLTE_RRC_DL_DCCH_MSG_TYPE_RRC_CON_RECONFIG: case LIBLTE_RRC_DL_DCCH_MSG_TYPE_RRC_CON_RECONFIG:
transaction_id = dl_dcch_msg.msg.rrc_con_reconfig.rrc_transaction_id; 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; break;
case LIBLTE_RRC_DL_DCCH_MSG_TYPE_UE_CAPABILITY_ENQUIRY: case LIBLTE_RRC_DL_DCCH_MSG_TYPE_UE_CAPABILITY_ENQUIRY:
transaction_id = dl_dcch_msg.msg.ue_cap_enquiry.rrc_transaction_id; 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++) { 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]) { 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; break;
} }
} }
@ -1743,7 +1740,7 @@ void rrc::enable_capabilities() {
phy->set_config_64qam_en(enable_ul_64); 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"); rrc_log->debug("Preparing UE Capability Info\n");
ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_UE_CAPABILITY_INFO; 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); liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf);
send_ul_dcch_msg(pdu); send_ul_dcch_msg();
} }

@ -109,6 +109,15 @@ imei = 353490069873319
#ue_category = 4 #ue_category = 4
#feature_group = 0xe6041c00 #feature_group = 0xe6041c00
#####################################################################
# NAS configuration
#
# apn: Set Access Point Name (APN)
#####################################################################
[nas]
# apn = internetinternet
[gui] [gui]
enable = false enable = false

Loading…
Cancel
Save