diff --git a/lib/include/srslte/asn1/gtpc_ies.h b/lib/include/srslte/asn1/gtpc_ies.h index 0ddcfaacb..215021584 100644 --- a/lib/include/srslte/asn1/gtpc_ies.h +++ b/lib/include/srslte/asn1/gtpc_ies.h @@ -330,8 +330,30 @@ struct gtpc_pdn_address_allocation_ie struct in6_addr ipv6; }; +/**************************************************************************** + * + * GTP-C Bearer Quality of Service IE + * Ref: 3GPP TS 29.274 v10.14.0 Figure 8.15-1 + * + ***************************************************************************/ +struct gtpc_bearer_qos_ie +{ + struct { + uint8_t pvi : 1; + uint8_t spare : 1; + uint8_t pl : 4; + uint8_t pci : 1; + uint8_t spare2 : 1; + } arp; + uint8_t qci; + uint8_t mbr_ul; + uint8_t mbr_dl; + uint8_t gbr_ul; + uint8_t gbr_dl; +}; + //TODO -//TODO IEs between 8.15 and 8.17 missing +//TODO IEs between 8.16 and 8.17 missing //TODO /**************************************************************************** diff --git a/lib/include/srslte/asn1/gtpc_msg.h b/lib/include/srslte/asn1/gtpc_msg.h index 61591d7c4..42b6ad3cf 100644 --- a/lib/include/srslte/asn1/gtpc_msg.h +++ b/lib/include/srslte/asn1/gtpc_msg.h @@ -202,6 +202,7 @@ struct gtpc_create_session_request struct gtpc_f_teid_ie s12_rnc_f_teid; bool s2b_u_epdg_f_teid_present; struct gtpc_f_teid_ie s2b_u_epdg_f_teid; + struct gtpc_bearer_qos_ie bearer_qos; // M } eps_bearer_context_created; // M //bool bearer_context_deleted_present; //struct bearer_context_ bearer_context_deleted; // C @@ -268,8 +269,8 @@ struct gtpc_create_session_response struct gtpc_f_teid_ie s12_sgw_f_teid; bool s2b_u_pgw_f_teid_present; struct gtpc_f_teid_ie s2b_u_pgw_f_teid; - //bearer_level_qos_present - //bearer_level_qos + bool bearer_level_qos_present; + struct gtpc_bearer_qos_ie bearer_level_qos; //charging_id_present //charging_id //bearer_flags_present diff --git a/lib/include/srslte/interfaces/epc_interfaces.h b/lib/include/srslte/interfaces/epc_interfaces.h index 60238b7f9..703a59912 100644 --- a/lib/include/srslte/interfaces/epc_interfaces.h +++ b/lib/include/srslte/interfaces/epc_interfaces.h @@ -11,6 +11,7 @@ class hss_interface_s1ap { public: virtual bool gen_auth_info_answer(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres) = 0; + virtual bool gen_update_loc_answer(uint64_t imsi, uint8_t *qci) = 0; virtual bool resync_sqn(uint64_t imsi, uint8_t *auts) = 0; }; diff --git a/srsepc/hdr/hss/hss.h b/srsepc/hdr/hss/hss.h index 4df632d83..7160cb54d 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -60,6 +60,7 @@ typedef struct{ uint8_t opc[16]; uint8_t amf[2]; uint8_t sqn[6]; + uint16_t qci; uint8_t last_rand[16]; }hss_ue_ctx_t; @@ -77,6 +78,8 @@ public: void stop(void); bool gen_auth_info_answer(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres); + bool gen_update_loc_answer(uint64_t imsi, uint8_t* qci); + bool resync_sqn(uint64_t imsi, uint8_t *auts); private: diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index 7465f9696..262d034b1 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -111,7 +111,7 @@ typedef struct{ typedef struct{ uint8_t eksi; - uint8_t k_asme[32]; + uint8_t k_asme[32]; uint8_t xres[16]; //minimum 6, maximum 16 uint32_t dl_nas_count; uint32_t ul_nas_count; @@ -128,6 +128,7 @@ typedef struct{ typedef struct{ enum erab_state state; uint8_t erab_id; + uint8_t qci; srslte::gtpc_f_teid_ie enb_fteid; srslte::gtpc_f_teid_ie sgw_s1u_fteid; srslte::gtpc_pdn_address_allocation_ie pdn_addr_alloc; @@ -160,7 +161,6 @@ typedef struct{ ue_emm_ctx_t emm_ctx; eps_sec_ctx_t sec_ctx; ue_ecm_ctx_t ecm_ctx; - erab_ctx_t erabs_ctx[MAX_ERABS_PER_UE]; } ue_ctx_t; }//namespace diff --git a/srsepc/src/hss/hss.cc b/srsepc/src/hss/hss.cc index cd48f23c1..6bbf86097 100644 --- a/srsepc/src/hss/hss.cc +++ b/srsepc/src/hss/hss.cc @@ -153,7 +153,7 @@ hss::read_db_file(std::string db_filename) { if(line[0] != '#') { - uint column_size = 7; + uint column_size = 8; std::vector split = split_string(line,','); if(split.size() != column_size) { @@ -192,7 +192,8 @@ hss::read_db_file(std::string db_filename) m_hss_log->debug_hex(ue_ctx->opc, 16, "User OPc : "); m_hss_log->debug_hex(ue_ctx->amf, 2, "AMF : "); m_hss_log->debug_hex(ue_ctx->sqn, 6, "SQN : "); - + ue_ctx->qci = atoi(split[7].c_str()); + m_hss_log->debug("Default Bearer QCI: %d\n",ue_ctx->qci); m_imsi_to_ue_ctx.insert(std::pair(ue_ctx->imsi,ue_ctx)); } } @@ -225,7 +226,7 @@ bool hss::write_db_file(std::string db_filename) //Write comment info m_db_file << "# " << std::endl << "# .csv to store UE's information in HSS " << std::endl - << "# Kept in the following format: \"Name,IMSI,Key,OP_Type,OP,AMF,SQN\" " << std::endl + << "# Kept in the following format: \"Name,IMSI,Key,OP_Type,OP,AMF,SQN,QCI\" " << std::endl << "# " << std::endl << "# Name: Human readable name to help distinguish UE's. Ignored by the HSS " << std::endl << "# IMSI: UE's IMSI value " << std::endl @@ -234,6 +235,7 @@ bool hss::write_db_file(std::string db_filename) << "# OP/OPc: Operator Code/Cyphered Operator Code, stored in hexadecimal " << std::endl << "# AMF: Authentication management field, stored in hexadecimal " << std::endl << "# SQN: UE's Sequence number for freshness of the authentication " << std::endl + << "# QCI: QoS Class Identifier for the UE's default bearer. " << std::endl << "# " << std::endl << "# Note: Lines starting by '#' are ignored and will be overwritten " << std::endl; @@ -258,10 +260,11 @@ bool hss::write_db_file(std::string db_filename) m_db_file << hex_string(it->second->amf, 2); m_db_file << ","; m_db_file << hex_string(it->second->sqn, 6); + m_db_file << ","; + m_db_file << it->second->qci; m_db_file << std::endl; it++; } - if(m_db_file.is_open()) { m_db_file.close(); @@ -287,89 +290,7 @@ hss::gen_auth_info_answer(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t } -bool -hss::resync_sqn(uint64_t imsi, uint8_t *auts) -{ - bool ret = false; - switch (m_auth_algo) - { - case HSS_ALGO_XOR: - ret = resync_sqn_xor(imsi, auts); - break; - case HSS_ALGO_MILENAGE: - ret = resync_sqn_milenage(imsi, auts); - break; - } - increment_ue_sqn(imsi); - return ret; -} - -bool -hss::resync_sqn_xor(uint64_t imsi, uint8_t *auts) -{ - m_hss_log->error("XOR SQN synchronization not supported yet\n"); - m_hss_log->console("XOR SQNs synchronization not supported yet\n"); - return false; -} - - -bool -hss::resync_sqn_milenage(uint64_t imsi, uint8_t *auts) -{ - uint8_t last_rand[16]; - uint8_t ak[6]; - uint8_t mac_s[8]; - uint8_t sqn_ms_xor_ak[6]; - - uint8_t k[16]; - uint8_t amf[2]; - uint8_t opc[16]; - uint8_t sqn[6]; - - if(!get_k_amf_opc_sqn(imsi, k, amf, opc, sqn)) - { - return false; - } - - get_last_rand(imsi, last_rand); - - for(int i=0; i<6; i++){ - sqn_ms_xor_ak[i] = auts[i]; - } - - for(int i=0; i<8; i++){ - mac_s[i] = auts[i+6]; - } - - m_hss_log->debug_hex(k, 16, "User Key : "); - m_hss_log->debug_hex(opc, 16, "User OPc : "); - m_hss_log->debug_hex(last_rand, 16, "User Last Rand : "); - m_hss_log->debug_hex(auts, 16, "AUTS : "); - m_hss_log->debug_hex(sqn_ms_xor_ak, 6, "SQN xor AK : "); - m_hss_log->debug_hex(mac_s, 8, "MAC : "); - - security_milenage_f5_star(k, opc, last_rand, ak); - m_hss_log->debug_hex(ak, 6, "Resynch AK : "); - - uint8_t sqn_ms[6]; - for(int i=0; i<6; i++){ - sqn_ms[i] = sqn_ms_xor_ak[i] ^ ak[i]; - } - m_hss_log->debug_hex(sqn_ms, 6, "SQN MS : "); - m_hss_log->debug_hex(sqn , 6, "SQN HE : "); - - m_hss_log->debug_hex(amf, 2, "AMF : "); - - uint8_t mac_s_tmp[8]; - - security_milenage_f1_star(k, opc, last_rand, sqn_ms, amf, mac_s_tmp); - - m_hss_log->debug_hex(mac_s_tmp, 8, "MAC calc : "); - set_sqn(imsi, sqn_ms); - - return true; -} bool hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres) @@ -534,7 +455,7 @@ hss::gen_auth_info_answer_xor(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uin mcc, mnc, k_asme); - + m_hss_log->debug("User MCC : %x MNC : %x \n", mcc, mnc); m_hss_log->debug_hex(k_asme, 32, "User k_asme : "); @@ -559,6 +480,23 @@ hss::gen_auth_info_answer_xor(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uin return true; } +bool +hss::gen_update_loc_answer(uint64_t imsi, uint8_t* qci) +{ + std::map::iterator ue_ctx_it = m_imsi_to_ue_ctx.find(imsi); + if(ue_ctx_it == m_imsi_to_ue_ctx.end()) + { + m_hss_log->info("User not found. IMSI: %015lu\n",imsi); + m_hss_log->console("User not found. IMSI: %015lu\n",imsi); + return false; + } + hss_ue_ctx_t *ue_ctx = ue_ctx_it->second; + m_hss_log->info("Found User %015lu\n",imsi); + *qci = ue_ctx->qci; + return true; +} + + bool hss::get_k_amf_opc_sqn(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *opc, uint8_t *sqn) @@ -581,6 +519,90 @@ hss::get_k_amf_opc_sqn(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *opc, ui return true; } +bool +hss::resync_sqn(uint64_t imsi, uint8_t *auts) +{ + bool ret = false; + switch (m_auth_algo) + { + case HSS_ALGO_XOR: + ret = resync_sqn_xor(imsi, auts); + break; + case HSS_ALGO_MILENAGE: + ret = resync_sqn_milenage(imsi, auts); + break; + } + increment_ue_sqn(imsi); + return ret; +} + +bool +hss::resync_sqn_xor(uint64_t imsi, uint8_t *auts) +{ + m_hss_log->error("XOR SQN synchronization not supported yet\n"); + m_hss_log->console("XOR SQNs synchronization not supported yet\n"); + return false; +} + + +bool +hss::resync_sqn_milenage(uint64_t imsi, uint8_t *auts) +{ + uint8_t last_rand[16]; + uint8_t ak[6]; + uint8_t mac_s[8]; + uint8_t sqn_ms_xor_ak[6]; + + uint8_t k[16]; + uint8_t amf[2]; + uint8_t opc[16]; + uint8_t sqn[6]; + + if(!get_k_amf_opc_sqn(imsi, k, amf, opc, sqn)) + { + return false; + } + + get_last_rand(imsi, last_rand); + + for(int i=0; i<6; i++){ + sqn_ms_xor_ak[i] = auts[i]; + } + + for(int i=0; i<8; i++){ + mac_s[i] = auts[i+6]; + } + + m_hss_log->debug_hex(k, 16, "User Key : "); + m_hss_log->debug_hex(opc, 16, "User OPc : "); + m_hss_log->debug_hex(last_rand, 16, "User Last Rand : "); + m_hss_log->debug_hex(auts, 16, "AUTS : "); + m_hss_log->debug_hex(sqn_ms_xor_ak, 6, "SQN xor AK : "); + m_hss_log->debug_hex(mac_s, 8, "MAC : "); + + security_milenage_f5_star(k, opc, last_rand, ak); + m_hss_log->debug_hex(ak, 6, "Resynch AK : "); + + uint8_t sqn_ms[6]; + for(int i=0; i<6; i++){ + sqn_ms[i] = sqn_ms_xor_ak[i] ^ ak[i]; + } + m_hss_log->debug_hex(sqn_ms, 6, "SQN MS : "); + m_hss_log->debug_hex(sqn , 6, "SQN HE : "); + + m_hss_log->debug_hex(amf, 2, "AMF : "); + + uint8_t mac_s_tmp[8]; + + security_milenage_f1_star(k, opc, last_rand, sqn_ms, amf, mac_s_tmp); + + m_hss_log->debug_hex(mac_s_tmp, 8, "MAC calc : "); + + set_sqn(imsi, sqn_ms); + + return true; +} + void hss::increment_ue_sqn(uint64_t imsi) { @@ -613,6 +635,7 @@ hss::increment_sqn(uint8_t *sqn, uint8_t *next_sqn) } return; } + void hss::set_sqn(uint64_t imsi, uint8_t *sqn) { @@ -668,7 +691,7 @@ bool hss::get_ue_ctx(uint64_t imsi, hss_ue_ctx_t **ue_ctx) m_hss_log->info("User not found. IMSI: %015lu\n",imsi); return false; } - + *ue_ctx = ue_ctx_it->second; return true; } @@ -713,15 +736,4 @@ hss::hex_string(uint8_t *hex, int size) } return ss.str(); } - /* -uint64_t -string_to_imsi() -{ - uint64_t imsi = 0; - for(int i=0;i<=14;i++){ - imsi += attach_req.eps_mobile_id.imsi[i]*std::pow(10,14-i); - } - return imsi; -} - */ } //namespace srsepc diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 7c30bfa3b..6ef0e2cbb 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -124,9 +124,13 @@ mme_gtpc::send_create_session_request(uint64_t imsi) // APN strncpy(cs_req->apn, m_s1ap->m_s1ap_args.mme_apn.c_str(), sizeof(cs_req->apn)-1); cs_req->apn[sizeof(cs_req->apn)-1] = 0; + // RAT Type //cs_req->rat_type = srslte::GTPC_RAT_TYPE::EUTRAN; + //Bearer QoS + cs_req->eps_bearer_context_created.ebi = 5; + //Check whether this UE is already registed std::map::iterator it = m_imsi_to_gtpc_ctx.find(imsi); if(it != m_imsi_to_gtpc_ctx.end()) @@ -243,10 +247,9 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu) //Set EPS bearer context //FIXME default EPS bearer is hard-coded int default_bearer=5; - erab_ctx_t *erab_ctx = &ecm_ctx->erabs_ctx[default_bearer]; + erab_ctx_t *erab_ctx = &ecm_ctx->erabs_ctx[default_bearer]; erab_ctx->pdn_addr_alloc= cs_resp->paa; erab_ctx->sgw_s1u_fteid = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid; - m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(emm_ctx, ecm_ctx, erab_ctx); return; } diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 2ba49ae01..b9d599d3e 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -114,13 +114,13 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, in_ctxt_req->E_RABToBeSetupListCtxtSUReq.len = 1; erab_ctx_req->e_RAB_ID.E_RAB_ID = erab_ctx->erab_id; //Setup E-RAB QoS parameters - erab_ctx_req->e_RABlevelQoSParameters.qCI.QCI = 9; + erab_ctx_req->e_RABlevelQoSParameters.qCI.QCI = erab_ctx->qci; erab_ctx_req->e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel.PriorityLevel = 15 ;//Lowest erab_ctx_req->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionCapability = LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_SHALL_NOT_TRIGGER_PRE_EMPTION; erab_ctx_req->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability = LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_PRE_EMPTABLE; - erab_ctx_req->e_RABlevelQoSParameters.gbrQosInformation_present=false; - + + //Set E-RAB S-GW F-TEID //if (cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid_present == false){ // m_s1ap_log->error("Did not receive S1-U TEID in create session response\n"); @@ -188,8 +188,6 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, //Change E-RAB state to Context Setup Requested and save S-GW control F-TEID ecm_ctx->erabs_ctx[erab_ctx_req->e_RAB_ID.E_RAB_ID].state = ERAB_CTX_REQUESTED; - //ecm_ctx->erabs_ctx[erab_ctx_req->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.teid = sgw_ctrl_fteid.teid; - //ecm_ctx->erabs_ctx[erab_ctx_req->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.ipv4 = sgw_ctrl_fteid.ipv4; struct in_addr addr; addr.s_addr = htonl(sgw_s1u_ip); @@ -199,6 +197,7 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, m_s1ap_log->console("Initial Context Setup Request -- E-RAB id %d\n",erab_ctx_req->e_RAB_ID.E_RAB_ID); m_s1ap_log->console("Initial Context Setup Request -- S1-U TEID 0x%x. IP %s \n", sgw_s1u_teid,inet_ntoa(addr)); m_s1ap_log->console("Initial Context Setup Request -- S1-U TEID 0x%x. IP %s \n", sgw_s1u_teid,inet_ntoa(addr)); + m_s1ap_log->console("Initial Context Setup Request -- QCI %d \n", erab_ctx_req->e_RABlevelQoSParameters.qCI.QCI); m_pool->deallocate(reply_buffer); m_pool->deallocate(nas_buffer); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 821ccf1bf..a527cf029 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -139,7 +139,7 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA m_s1ap_log->info("Detach Request -- S-TMSI 0x%x\n", ntohl(*m_tmsi)); m_s1ap_log->console("Detach Request -- S-TMSI 0x%x\n", ntohl(*m_tmsi) ); m_s1ap_log->info("Detach Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); - m_s1ap_log->console("Detach Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); + m_s1ap_log->console("Detach Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); handle_nas_detach_request(ntohl(*m_tmsi), enb_ue_s1ap_id, nas_msg, reply_buffer,reply_flag, enb_sri); return true; @@ -227,9 +227,8 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA (msg_type == LIBLTE_MME_MSG_TYPE_AUTHENTICATION_FAILURE && sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY)) { //Only identity response and authentication response are valid as plain NAS. - //Sometimes authentication response and identity are sent as integrity protected, + //Sometimes authentication response/failure and identity response are sent as integrity protected, //but these messages are sent when the securty context is not setup yet, so we cannot integrity check it. - //FIXME Double-check switch(msg_type) { case LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE: @@ -710,6 +709,11 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, } else { + //Get subscriber info from HSS + uint8_t default_bearer=5; + m_hss->gen_update_loc_answer(emm_ctx->imsi,&ue_ctx->ecm_ctx.erabs_ctx[default_bearer].qci); + m_s1ap_log->debug("Getting subscription information -- QCI %d\n", ue_ctx->ecm_ctx.erabs_ctx[default_bearer].qci); + m_s1ap_log->console("Getting subscription information -- QCI %d\n", ue_ctx->ecm_ctx.erabs_ctx[default_bearer].qci); m_mme_gtpc->send_create_session_request(emm_ctx->imsi); *reply_flag = false; //No reply needed } @@ -1082,6 +1086,11 @@ s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas } else { + //Get subscriber info from HSS + uint8_t default_bearer=5; + m_hss->gen_update_loc_answer(emm_ctx->imsi,&ue_ctx->ecm_ctx.erabs_ctx[default_bearer].qci); + m_s1ap_log->debug("Getting subscription information -- QCI %d\n", ue_ctx->ecm_ctx.erabs_ctx[default_bearer].qci); + m_s1ap_log->console("Getting subscription information -- QCI %d\n", ue_ctx->ecm_ctx.erabs_ctx[default_bearer].qci); //FIXME The packging of GTP-C messages is not ready. //This means that GTP-U tunnels are created with function calls, as opposed to GTP-C. m_mme_gtpc->send_create_session_request(emm_ctx->imsi); @@ -1163,6 +1172,12 @@ s1ap_nas_transport::handle_esm_information_response(srslte::byte_buffer_t *nas_m m_s1ap_log->console("ESM Info: %d Protocol Configuration Options\n",esm_info_resp.protocol_cnfg_opts.N_opts); } + //Get subscriber info from HSS + uint8_t default_bearer=5; + m_hss->gen_update_loc_answer(ue_ctx->emm_ctx.imsi,&ue_ctx->ecm_ctx.erabs_ctx[default_bearer].qci); + m_s1ap_log->debug("Getting subscription information -- QCI %d\n", ue_ctx->ecm_ctx.erabs_ctx[default_bearer].qci); + m_s1ap_log->console("Getting subscription information -- QCI %d\n", ue_ctx->ecm_ctx.erabs_ctx[default_bearer].qci); + //FIXME The packging of GTP-C messages is not ready. //This means that GTP-U tunnels are created with function calls, as opposed to GTP-C. m_mme_gtpc->send_create_session_request(ue_ctx->emm_ctx.imsi); diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index a759bf3bc..4877ddeb9 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -536,6 +536,7 @@ spgw::handle_create_session_request(struct srslte::gtpc_create_session_request * cs_resp->eps_bearer_context_created.cause.cause_value = srslte::GTPC_CAUSE_VALUE_REQUEST_ACCEPTED; cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid_present=true; cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid = tunnel_ctx->up_user_fteid; + //Fill in the PAA cs_resp->paa_present = true; cs_resp->paa.pdn_type = srslte::GTPC_PDN_TYPE_IPV4; diff --git a/srsepc/user_db.csv.example b/srsepc/user_db.csv.example index 55db2e44c..77ab1e7a8 100644 --- a/srsepc/user_db.csv.example +++ b/srsepc/user_db.csv.example @@ -1,6 +1,6 @@ # # .csv to store UE's information in HSS -# Kept in the following format: "Name,IMSI,Key,OP_Type,OP,AMF,SQN" +# Kept in the following format: "Name,IMSI,Key,OP_Type,OP,AMF,SQN,QCI" # # Name: Human readable name to help distinguish UE's. Ignored by the HSS # IMSI: UE's IMSI value @@ -9,7 +9,8 @@ # OP/OPc: Operator Code/Cyphered Operator Code, stored in hexadecimal # AMF: Authentication management field, stored in hexadecimal # SQN: UE's Sequence number for freshness of the authentication +# QCI: QoS Class Identifier for the UE's default bearer. # # Note: Lines starting by '#' are ignored and will be overwritten -ue1,001010123456789,00112233445566778899aabbccddeeff,opc,63bfa50ee6523365ff14c1f45f88737d,9001,000000001234 -ue2,001010123456780,00112233445566778899aabbccddeeff,opc,63bfa50ee6523365ff14c1f45f88737d,8000,000000001234 +ue1,001010123456789,00112233445566778899aabbccddeeff,opc,63bfa50ee6523365ff14c1f45f88737d,9001,000000001234,9 +ue2,001010123456780,00112233445566778899aabbccddeeff,opc,63bfa50ee6523365ff14c1f45f88737d,8000,000000001234,7