Enable S-TMSI attach

master
Ismael Gomez 7 years ago
parent 49a621e193
commit c6e947e7ca

@ -38,6 +38,7 @@
#include "srslte/radio/radio_multi.h" #include "srslte/radio/radio_multi.h"
#include "phy/phy.h" #include "phy/phy.h"
#include "upper/usim.h" #include "upper/usim.h"
#include "upper/rrc.h"
#include "srslte/interfaces/ue_interfaces.h" #include "srslte/interfaces/ue_interfaces.h"
#include "srslte/common/logger.h" #include "srslte/common/logger.h"
@ -107,7 +108,6 @@ typedef struct {
phy_args_t phy; phy_args_t phy;
float metrics_period_secs; float metrics_period_secs;
bool pregenerate_signals; bool pregenerate_signals;
std::string ue_cateogry;
bool metrics_csv_enable; bool metrics_csv_enable;
std::string metrics_csv_filename; std::string metrics_csv_filename;
}expert_args_t; }expert_args_t;
@ -120,6 +120,8 @@ typedef struct {
log_args_t log; log_args_t log;
gui_args_t gui; gui_args_t gui;
usim_args_t usim; usim_args_t usim;
rrc_args_t rrc;
std::string ue_category_str;
expert_args_t expert; expert_args_t expert;
}all_args_t; }all_args_t;

@ -39,6 +39,15 @@
#include <map> #include <map>
typedef struct {
bool stmsi_attach;
LIBLTE_RRC_S_TMSI_STRUCT stmsi_value;
uint32_t ue_category;
uint32_t feature_group;
uint8_t supported_bands[LIBLTE_RRC_BAND_N_ITEMS];
uint32_t nof_supported_bands;
}rrc_args_t;
using srslte::byte_buffer_t; using srslte::byte_buffer_t;
namespace srsue { namespace srsue {
@ -73,7 +82,7 @@ public:
rrc_state_t get_state(); rrc_state_t get_state();
void set_ue_category(int category); void set_args(rrc_args_t *args);
// Timeout callback interface // Timeout callback interface
void timer_expired(uint32_t timeout_id); void timer_expired(uint32_t timeout_id);
@ -98,6 +107,9 @@ private:
uint8_t transaction_id; uint8_t transaction_id;
bool drb_up; bool drb_up;
rrc_args_t args;
bool first_stimsi_attempt;
bool reestablishment_in_progress; bool reestablishment_in_progress;
// timeouts in ms // timeouts in ms
@ -132,7 +144,6 @@ private:
uint32_t n310_cnt, N310; uint32_t n310_cnt, N310;
uint32_t n311_cnt, N311; uint32_t n311_cnt, N311;
uint32_t t301, t310, t311; uint32_t t301, t310, t311;
int ue_category;
typedef struct { typedef struct {
uint32_t earfcn; uint32_t earfcn;
@ -270,6 +281,10 @@ private:
void set_rrc_default(); void set_rrc_default();
void set_bearers(); void set_bearers();
// s-tmsi persistent file
bool read_stimsi_file(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi);
bool write_stimsi_file(LIBLTE_RRC_S_TMSI_STRUCT s_tmsi);
}; };
} // namespace srsue } // namespace srsue

@ -75,8 +75,17 @@ void parse_args(all_args_t *args, int argc, char *argv[]) {
("rf.device_args", bpo::value<string>(&args->rf.device_args)->default_value("auto"), "Front-end device arguments") ("rf.device_args", bpo::value<string>(&args->rf.device_args)->default_value("auto"), "Front-end device arguments")
("rf.time_adv_nsamples", bpo::value<string>(&args->rf.time_adv_nsamples)->default_value("auto"), ("rf.time_adv_nsamples", bpo::value<string>(&args->rf.time_adv_nsamples)->default_value("auto"),
"Transmission time advance") "Transmission time advance")
("rf.burst_preamble_us", bpo::value<string>(&args->rf.burst_preamble)->default_value("auto"), ("rf.burst_preamble_us", bpo::value<string>(&args->rf.burst_preamble)->default_value("auto"), "Transmission time advance")
"Transmission time advance")
("rrc.stmsi_attach", bpo::value<bool>(&args->rrc.stmsi_attach)->default_value(false),"If enabled, always tries first an S-TMSI attach using the\n"
"S-TMSI value stored in .stimsi file generated in previous run")
("rrc.mmec_value", bpo::value<uint8_t>(&args->rrc.stmsi_value.mmec)->default_value(0), "If defined (non-zero), overwrites the value stored in .stimsi file")
("rrc.mtmsi_value", bpo::value<uint32_t>(&args->rrc.stmsi_value.m_tmsi)->default_value(0), "If defined (non-zero), overwrites the value stored in .stimsi file")
("rrc.feature_group", bpo::value<uint32_t>(&args->rrc.feature_group)->default_value(0xe6041c00), "Hex value of the featureGroupIndicators field in the"
"UECapabilityInformation message. Default 0xe6041c00")
("rrc.ue_category", bpo::value<string>(&args->ue_category_str)->default_value("4"), "UE Category (1 to 5)")
("pcap.enable", bpo::value<bool>(&args->pcap.enable)->default_value(false), ("pcap.enable", bpo::value<bool>(&args->pcap.enable)->default_value(false),
"Enable MAC packet captures for wireshark") "Enable MAC packet captures for wireshark")
@ -134,10 +143,6 @@ void parse_args(all_args_t *args, int argc, char *argv[]) {
bpo::value<int>(&args->expert.phy.sync_cpu_affinity)->default_value(-1), bpo::value<int>(&args->expert.phy.sync_cpu_affinity)->default_value(-1),
"index of the core used by the sync thread") "index of the core used by the sync thread")
("expert.ue_category",
bpo::value<string>(&args->expert.ue_cateogry)->default_value("4"),
"UE Category (1 to 5)")
("expert.metrics_period_secs", ("expert.metrics_period_secs",
bpo::value<float>(&args->expert.metrics_period_secs)->default_value(1.0), bpo::value<float>(&args->expert.metrics_period_secs)->default_value(1.0),
"Periodicity for metrics in seconds") "Periodicity for metrics in seconds")

@ -188,7 +188,12 @@ bool ue::init(all_args_t *args_)
gw.set_netmask(args->expert.ip_netmask); gw.set_netmask(args->expert.ip_netmask);
rrc.init(&phy, &mac, &rlc, &pdcp, &nas, &usim, &mac, &rrc_log); rrc.init(&phy, &mac, &rlc, &pdcp, &nas, &usim, &mac, &rrc_log);
rrc.set_ue_category(atoi(args->expert.ue_cateogry.c_str()));
// Get current band from provided EARFCN
args->rrc.supported_bands[0] = srslte_band_get_band(args->rf.dl_earfcn);
args->rrc.nof_supported_bands = 1;
args->rrc.ue_category = atoi(args->ue_category_str.c_str());
rrc.set_args(&args->rrc);
// Currently EARFCN list is set to only one frequency as indicated in ue.conf // Currently EARFCN list is set to only one frequency as indicated in ue.conf
std::vector<uint32_t> earfcn_list; std::vector<uint32_t> earfcn_list;

@ -26,12 +26,11 @@
#include <unistd.h> #include <unistd.h>
#include <iostream>
#include <fstream>
#include <sstream> #include <sstream>
#include "srslte/asn1/liblte_rrc.h"
#include "upper/rrc.h" #include "upper/rrc.h"
#include <boost/assign.hpp> #include "srslte/asn1/liblte_rrc.h"
#include <upper/rrc.h>
#include <srslte/asn1/liblte_rrc.h>
#include "srslte/common/security.h" #include "srslte/common/security.h"
#include "srslte/common/bcd_helpers.h" #include "srslte/common/bcd_helpers.h"
@ -93,9 +92,15 @@ void rrc::init(phy_interface_rrc *phy_,
pthread_mutex_init(&mutex, NULL); pthread_mutex_init(&mutex, NULL);
first_stimsi_attempt = false;
reestablishment_in_progress = false; reestablishment_in_progress = false;
ue_category = SRSLTE_UE_CATEGORY; args.ue_category = SRSLTE_UE_CATEGORY;
args.supported_bands[0] = 7;
args.nof_supported_bands = 1;
args.feature_group = 0xe6041c00;
args.stmsi_attach = false;
t301 = mac_timers->timer_get_unique_id(); t301 = mac_timers->timer_get_unique_id();
t310 = mac_timers->timer_get_unique_id(); t310 = mac_timers->timer_get_unique_id();
t311 = mac_timers->timer_get_unique_id(); t311 = mac_timers->timer_get_unique_id();
@ -131,12 +136,8 @@ bool rrc::have_drb() {
return drb_up; return drb_up;
} }
void rrc::set_ue_category(int category) { void rrc::set_args(rrc_args_t *args) {
if (category >= 1 && category <= 5) { memcpy(&this->args, args, sizeof(rrc_args_t));
ue_category = category;
} else {
rrc_log->error("Unsupported UE category %d\n", category);
}
} }
/* /*
@ -591,6 +592,66 @@ void rrc::timer_expired(uint32_t timeout_id) {
* *
*******************************************************************************/ *******************************************************************************/
bool rrc::read_stimsi_file(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi) {
std::ifstream file;
std::string line;
if (!s_tmsi) {
return false;
}
const char *mmec_str = "mmec=";
size_t mmec_str_len = strlen(mmec_str);
const char *mtmsi_str = "mtmsi=";
size_t mtmsi_str_len = strlen(mtmsi_str);
file.open(".stmsi", std::ios::in);
if (file.is_open()) {
bool read_ok = true;
if (std::getline(file, line)) {
if (!line.substr(0,mmec_str_len).compare(mmec_str)) {
s_tmsi->mmec = atoi(line.substr(5).c_str());
} else {
read_ok = false;
}
} else {
read_ok = false;
}
if (std::getline(file, line)) {
if (!line.substr(0,mtmsi_str_len).compare(mtmsi_str)) {
s_tmsi->m_tmsi = atoi(line.substr(mtmsi_str_len).c_str());
} else {
read_ok = false;
}
} else {
read_ok = false;
}
file.close();
if (read_ok) {
rrc_log->info("Read S-TMSI value: %x:%x\n", s_tmsi->mmec, s_tmsi->m_tmsi);
return true;
} else {
rrc_log->error("Invalid s-tmsi persistent file format\n");
return false;
}
} else {
return false;
}
}
bool rrc::write_stimsi_file(LIBLTE_RRC_S_TMSI_STRUCT s_tmsi) {
std::ofstream file;
file.open(".stmsi", std::ios::out | std::ios::trunc);
if (file.is_open()) {
file << "mmec=" << (int) s_tmsi.mmec << std::endl;
file << "mtmsi=" << (int) s_tmsi.m_tmsi << std::endl;
rrc_log->info("Saved S-TMSI in persistent file: %x:%x\n", s_tmsi.mmec, s_tmsi.m_tmsi);
file.close();
return true;
} else {
return false;
}
}
void rrc::send_con_request() { void rrc::send_con_request() {
rrc_log->debug("Preparing RRC Connection Request\n"); rrc_log->debug("Preparing RRC Connection Request\n");
LIBLTE_RRC_UL_CCCH_MSG_STRUCT ul_ccch_msg; LIBLTE_RRC_UL_CCCH_MSG_STRUCT ul_ccch_msg;
@ -598,13 +659,32 @@ void rrc::send_con_request() {
// Prepare ConnectionRequest packet // Prepare ConnectionRequest packet
ul_ccch_msg.msg_type = LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REQ; ul_ccch_msg.msg_type = LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REQ;
if (nas->get_s_tmsi(&s_tmsi)) { bool valid_stmsi = false;
if (nas->get_s_tmsi(&s_tmsi) || (args.stmsi_attach && !first_stimsi_attempt)) {
ul_ccch_msg.msg.rrc_con_req.ue_id_type = LIBLTE_RRC_CON_REQ_UE_ID_TYPE_S_TMSI; ul_ccch_msg.msg.rrc_con_req.ue_id_type = LIBLTE_RRC_CON_REQ_UE_ID_TYPE_S_TMSI;
if (nas->get_s_tmsi(&s_tmsi)) {
ul_ccch_msg.msg.rrc_con_req.ue_id.s_tmsi = s_tmsi; ul_ccch_msg.msg.rrc_con_req.ue_id.s_tmsi = s_tmsi;
valid_stmsi = true;
} else {
first_stimsi_attempt = true;
if (args.stmsi_value.m_tmsi) {
ul_ccch_msg.msg.rrc_con_req.ue_id.s_tmsi = args.stmsi_value;
valid_stmsi = true;
} else { } else {
if (!read_stimsi_file(&ul_ccch_msg.msg.rrc_con_req.ue_id.s_tmsi)) {
rrc_log->warning("Could not read S-TMSI from persistent file. Trying normal attach.\n");
} else {
valid_stmsi = true;
}
}
}
}
if (!valid_stmsi) {
ul_ccch_msg.msg.rrc_con_req.ue_id_type = LIBLTE_RRC_CON_REQ_UE_ID_TYPE_RANDOM_VALUE; ul_ccch_msg.msg.rrc_con_req.ue_id_type = LIBLTE_RRC_CON_REQ_UE_ID_TYPE_RANDOM_VALUE;
ul_ccch_msg.msg.rrc_con_req.ue_id.random = 1000; ul_ccch_msg.msg.rrc_con_req.ue_id.random = 1000;
} }
ul_ccch_msg.msg.rrc_con_req.cause = LIBLTE_RRC_CON_REQ_EST_CAUSE_MO_SIGNALLING; ul_ccch_msg.msg.rrc_con_req.cause = LIBLTE_RRC_CON_REQ_EST_CAUSE_MO_SIGNALLING;
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);
@ -876,6 +956,14 @@ void rrc::handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGU
nas_sdu->N_bytes = reconfig->ded_info_nas_list[i].N_bytes; nas_sdu->N_bytes = reconfig->ded_info_nas_list[i].N_bytes;
nas->write_pdu(lcid, nas_sdu); nas->write_pdu(lcid, nas_sdu);
} }
// Get S-TMSI from NAS and store it in persistent file
LIBLTE_RRC_S_TMSI_STRUCT s_tmsi;
if (nas->get_s_tmsi(&s_tmsi)) {
if (!write_stimsi_file(s_tmsi)) {
rrc_log->warning("Could not store S-TMSI in persistent file\n");
}
}
} }
/* Actions upon reception of RRCConnectionRelease 5.3.8.3 */ /* Actions upon reception of RRCConnectionRelease 5.3.8.3 */
@ -1022,10 +1110,12 @@ void rrc::write_pdu_pcch(byte_buffer_t *pdu) {
LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi_paged; LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi_paged;
for (uint32_t i = 0; i < pcch_msg.paging_record_list_size; i++) { for (uint32_t i = 0; i < pcch_msg.paging_record_list_size; i++) {
s_tmsi_paged = &pcch_msg.paging_record_list[i].ue_identity.s_tmsi; s_tmsi_paged = &pcch_msg.paging_record_list[i].ue_identity.s_tmsi;
rrc_log->info("Received paging (%d/%d) for UE 0x%x\n", i + 1, pcch_msg.paging_record_list_size, rrc_log->info("Received paging (%d/%d) for UE %x:%x\n", i + 1, pcch_msg.paging_record_list_size,
pcch_msg.paging_record_list[i].ue_identity.s_tmsi); pcch_msg.paging_record_list[i].ue_identity.s_tmsi.mmec,
rrc_log->console("Received paging (%d/%d) for UE 0x%x\n", i + 1, pcch_msg.paging_record_list_size, pcch_msg.paging_record_list[i].ue_identity.s_tmsi.m_tmsi);
pcch_msg.paging_record_list[i].ue_identity.s_tmsi); rrc_log->console("Received paging (%d/%d) for UE %x:%x\n", i + 1, pcch_msg.paging_record_list_size,
pcch_msg.paging_record_list[i].ue_identity.s_tmsi.mmec,
pcch_msg.paging_record_list[i].ue_identity.s_tmsi.m_tmsi);
if (s_tmsi.mmec == s_tmsi_paged->mmec && s_tmsi.m_tmsi == s_tmsi_paged->m_tmsi) { if (s_tmsi.mmec == s_tmsi_paged->mmec && s_tmsi.m_tmsi == s_tmsi_paged->m_tmsi) {
rrc_log->info("S-TMSI match in paging message\n"); rrc_log->info("S-TMSI match in paging message\n");
rrc_log->console("S-TMSI match in paging message\n"); rrc_log->console("S-TMSI match in paging message\n");
@ -1200,7 +1290,7 @@ void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) {
* *
*******************************************************************************/ *******************************************************************************/
void rrc::enable_capabilities() { void rrc::enable_capabilities() {
bool enable_ul_64 = ue_category >= 5 && current_cell->sib2.rr_config_common_sib.pusch_cnfg.enable_64_qam; bool enable_ul_64 = args.ue_category >= 5 && current_cell->sib2.rr_config_common_sib.pusch_cnfg.enable_64_qam;
rrc_log->info("%s 64QAM PUSCH\n", enable_ul_64 ? "Enabling" : "Disabling"); rrc_log->info("%s 64QAM PUSCH\n", enable_ul_64 ? "Enabling" : "Disabling");
phy->set_config_64qam_en(enable_ul_64); phy->set_config_64qam_en(enable_ul_64);
} }
@ -1218,7 +1308,7 @@ void rrc::send_rrc_ue_cap_info(uint32_t lcid, byte_buffer_t *pdu) {
LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *cap = &info->ue_capability_rat[0].eutra_capability; LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *cap = &info->ue_capability_rat[0].eutra_capability;
cap->access_stratum_release = LIBLTE_RRC_ACCESS_STRATUM_RELEASE_REL8; cap->access_stratum_release = LIBLTE_RRC_ACCESS_STRATUM_RELEASE_REL8;
cap->ue_category = ue_category; cap->ue_category = args.ue_category;
cap->pdcp_params.max_rohc_ctxts_present = false; cap->pdcp_params.max_rohc_ctxts_present = false;
cap->pdcp_params.supported_rohc_profiles[0] = false; cap->pdcp_params.supported_rohc_profiles[0] = false;
@ -1234,31 +1324,17 @@ void rrc::send_rrc_ue_cap_info(uint32_t lcid, byte_buffer_t *pdu) {
cap->phy_params.specific_ref_sigs_supported = false; cap->phy_params.specific_ref_sigs_supported = false;
cap->phy_params.tx_antenna_selection_supported = false; cap->phy_params.tx_antenna_selection_supported = false;
//TODO: Generate this from user input? cap->rf_params.N_supported_band_eutras = args.nof_supported_bands;
cap->rf_params.N_supported_band_eutras = 3; cap->meas_params.N_band_list_eutra = args.nof_supported_bands;
cap->rf_params.supported_band_eutra[0].band_eutra = 3; for (uint32_t i=0;i<args.nof_supported_bands;i++) {
cap->rf_params.supported_band_eutra[0].half_duplex = false; cap->rf_params.supported_band_eutra[i].band_eutra = args.supported_bands[i];
cap->rf_params.supported_band_eutra[1].band_eutra = 7; cap->rf_params.supported_band_eutra[i].half_duplex = false;
cap->rf_params.supported_band_eutra[1].half_duplex = false; cap->meas_params.band_list_eutra[i].N_inter_freq_need_for_gaps = 1;
cap->rf_params.supported_band_eutra[2].band_eutra = 20; cap->meas_params.band_list_eutra[i].inter_freq_need_for_gaps[0] = true;
cap->rf_params.supported_band_eutra[2].half_duplex = false; }
cap->meas_params.N_band_list_eutra = 3;
cap->meas_params.band_list_eutra[0].N_inter_freq_need_for_gaps = 3;
cap->meas_params.band_list_eutra[0].inter_freq_need_for_gaps[0] = true;
cap->meas_params.band_list_eutra[0].inter_freq_need_for_gaps[1] = true;
cap->meas_params.band_list_eutra[0].inter_freq_need_for_gaps[2] = true;
cap->meas_params.band_list_eutra[1].N_inter_freq_need_for_gaps = 3;
cap->meas_params.band_list_eutra[1].inter_freq_need_for_gaps[0] = true;
cap->meas_params.band_list_eutra[1].inter_freq_need_for_gaps[1] = true;
cap->meas_params.band_list_eutra[1].inter_freq_need_for_gaps[2] = true;
cap->meas_params.band_list_eutra[2].N_inter_freq_need_for_gaps = 3;
cap->meas_params.band_list_eutra[2].inter_freq_need_for_gaps[0] = true;
cap->meas_params.band_list_eutra[2].inter_freq_need_for_gaps[1] = true;
cap->meas_params.band_list_eutra[2].inter_freq_need_for_gaps[2] = true;
cap->feature_group_indicator_present = true; cap->feature_group_indicator_present = true;
cap->feature_group_indicator = 0x62001000; cap->feature_group_indicator = args.feature_group;
cap->inter_rat_params.utra_fdd_present = false; cap->inter_rat_params.utra_fdd_present = false;
cap->inter_rat_params.utra_tdd128_present = false; cap->inter_rat_params.utra_tdd128_present = false;
cap->inter_rat_params.utra_tdd384_present = false; cap->inter_rat_params.utra_tdd384_present = false;

@ -92,18 +92,35 @@ k = 00112233445566778899aabbccddeeff
imsi = 001010123456789 imsi = 001010123456789
imei = 353490069873319 imei = 353490069873319
#####################################################################
# RRC configuration
#
# stimsi_attach: If enabled, always tries first an S-TMSI attach using the
# S-TMSI value stored in .stimsi file generated in previous run
# mmec_value: If defined (non-zero), overwrites the value stored in .stimsi file
# m_tmsi_value: If defined (non-zero), overwrites the value stored in .stimsi file
#
# ue_category: Sets UE category (range 1-5). Default: 4
# feature_group: Hex value of the featureGroupIndicators field in the
# UECapabilityInformation message. Default 0xe6041c00
#####################################################################
[rrc]
#stmsi_attach = false
#mmec_value = 0
#mtmsi_value = 0
#ue_category = 4
#feature_group = 0xe6041c00
[gui] [gui]
enable = false enable = false
##################################################################### #####################################################################
# Expert configuration options # Expert configuration options
# #
# ue_category: Sets UE category (range 1-5). Default: 4
# ip_netmask: Netmask of the tun_srsue device. Default: 255.255.255.0 # ip_netmask: Netmask of the tun_srsue device. Default: 255.255.255.0
# rssi_sensor_enabled: Enable or disable RF frontend RSSI sensor. Required for RSRP metrics but # rssi_sensor_enabled: Enable or disable RF frontend RSSI sensor. Required for RSRP metrics but
# can cause UHD instability for long-duration testing. Default true. # can cause UHD instability for long-duration testing. Default true.
# ue_category: Sets UE category (range 1-5). Default: 4
#
# prach_gain: PRACH gain (dB). If defined, forces a gain for the tranmsission of PRACH only., # prach_gain: PRACH gain (dB). If defined, forces a gain for the tranmsission of PRACH only.,
# Default is to use tx_gain in [rf] section. # Default is to use tx_gain in [rf] section.
# cqi_max: Upper bound on the maximum CQI to be reported. Default 15. # cqi_max: Upper bound on the maximum CQI to be reported. Default 15.
@ -146,7 +163,6 @@ enable = false
[expert] [expert]
#ip_netmask = 255.255.255.0 #ip_netmask = 255.255.255.0
#rssi_sensor_enabled = false #rssi_sensor_enabled = false
#ue_category = 4
#prach_gain = 30 #prach_gain = 30
#cqi_max = 15 #cqi_max = 15
#cqi_fixed = 10 #cqi_fixed = 10

Loading…
Cancel
Save