add detach support (for switch off)

master
Andre Puschmann 6 years ago
parent ca429d2be5
commit 3b8371d090

@ -146,7 +146,7 @@ class nas_interface_ue
{
public:
virtual bool attach_request() = 0;
virtual bool deattach_request() = 0;
virtual bool detach_request() = 0;
};
// NAS interface for UE

@ -69,8 +69,8 @@ public:
bool init(all_args_t *args_);
void stop();
bool attach();
bool deattach();
bool switch_on();
bool switch_off();
bool is_attached();
void start_plot();
void print_mbms();

@ -159,8 +159,8 @@ public:
virtual bool init(all_args_t *args_) = 0;
virtual void stop() = 0;
virtual bool attach() = 0;
virtual bool deattach() = 0;
virtual bool switch_on() = 0;
virtual bool switch_off() = 0;
virtual bool is_attached() = 0;
virtual void start_plot() = 0;

@ -90,7 +90,7 @@ public:
// UE interface
bool attach_request();
bool deattach_request();
bool detach_request();
// PCAP
void start_pcap(srslte::nas_pcap *pcap_);
@ -186,6 +186,7 @@ private:
void send_authentication_failure(const uint8_t cause, const uint8_t* auth_fail_param);
void gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg);
void send_security_mode_reject(uint8_t cause);
void send_detach_request(bool switch_off);
// security context persistence file
bool read_ctxt_file(nas_sec_ctxt *ctxt);

@ -545,7 +545,7 @@ int main(int argc, char *argv[])
pthread_create(&input, NULL, &input_loop, &args);
printf("Attaching UE...\n");
while (!ue->attach() && running) {
while (!ue->switch_on() && running) {
sleep(1);
}
if (running) {
@ -585,6 +585,7 @@ int main(int argc, char *argv[])
}
sleep(1);
}
ue->switch_off();
pthread_cancel(input);
metricshub.stop();
ue->stop();

@ -301,12 +301,27 @@ void ue::stop()
}
}
bool ue::attach() {
bool ue::switch_on() {
return nas.attach_request();
}
bool ue::deattach() {
return nas.deattach_request();
bool ue::switch_off() {
// generate detach request
nas.detach_request();
// wait for max. 5s for it to be sent (according to TS 24.301 Sec 25.5.2.2)
const uint32_t RB_ID_SRB1 = 1;
int cnt = 0, timeout = 5;
while (rlc.get_buffer_state(RB_ID_SRB1) && ++cnt <= timeout) {
sleep(1);
}
bool detach_sent = true;
if (rlc.get_buffer_state(RB_ID_SRB1)) {
nas_log.warning("Detach couldn't be sent after %ds.\n", timeout);
detach_sent = false;
}
return detach_sent;
}
bool ue::is_attached()

@ -172,9 +172,25 @@ bool nas::attach_request() {
return false;
}
bool nas::deattach_request() {
state = EMM_STATE_DEREGISTERED_INITIATED;
nas_log->info("Dettach request not supported\n");
bool nas::detach_request() {
// attempt detach for 5s
nas_log->info("Detach Request\n");
switch (state) {
case EMM_STATE_DEREGISTERED:
// do nothing ..
break;
case EMM_STATE_REGISTERED:
// send detach request
send_detach_request(true);
state = EMM_STATE_DEREGISTERED_INITIATED;
break;
case EMM_STATE_DEREGISTERED_INITIATED:
// do nothing ..
break;
default:
break;
}
return false;
}
@ -1132,6 +1148,63 @@ void nas::send_security_mode_reject(uint8_t cause) {
rrc->write_sdu(cfg.lcid, msg);
}
void nas::send_detach_request(bool switch_off)
{
byte_buffer_t *pdu = pool_allocate_blocking;
if (!pdu) {
nas_log->error("Fatal Error: Couldn't allocate PDU in %s().\n", __FUNCTION__);
return;
}
LIBLTE_MME_DETACH_REQUEST_MSG_STRUCT detach_request = {};
if (switch_off) {
detach_request.detach_type.switch_off = 1;
detach_request.detach_type.type_of_detach = LIBLTE_MME_SO_FLAG_SWITCH_OFF;
} else {
detach_request.detach_type.switch_off = 0;
detach_request.detach_type.type_of_detach = LIBLTE_MME_SO_FLAG_NORMAL_DETACH;
}
// GUTI or IMSI detach
if (have_guti && have_ctxt) {
detach_request.eps_mobile_id.type_of_id = LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI;
memcpy(&detach_request.eps_mobile_id.guti, &ctxt.guti, sizeof(LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT));
detach_request.nas_ksi.tsc_flag = LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE;
detach_request.nas_ksi.nas_ksi = ctxt.ksi;
nas_log->info("Requesting Detach with GUTI\n");
liblte_mme_pack_detach_request_msg(&detach_request,
LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY,
ctxt.tx_count,
(LIBLTE_BYTE_MSG_STRUCT *) pdu);
// Add MAC
if (pdu->N_bytes > 5) {
integrity_generate(&k_nas_int[16],
ctxt.tx_count,
SECURITY_DIRECTION_UPLINK,
&pdu->msg[5],
pdu->N_bytes - 5,
&pdu->msg[1]);
} else {
nas_log->error("Invalid PDU size %d\n", pdu->N_bytes);
}
} else {
detach_request.eps_mobile_id.type_of_id = LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI;
detach_request.nas_ksi.tsc_flag = LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE;
detach_request.nas_ksi.nas_ksi = 0;
usim->get_imsi_vec(detach_request.eps_mobile_id.imsi, 15);
nas_log->info("Requesting IMSI detach (IMSI=%s)\n", usim->get_imsi_str().c_str());
liblte_mme_pack_detach_request_msg(&detach_request, LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT *) pdu);
}
if(pcap != NULL) {
pcap->write_nas(pdu->msg, pdu->N_bytes);
}
nas_log->info("Sending detach request\n");
rrc->write_sdu(cfg.lcid, pdu);
}
void nas::send_authentication_response(const uint8_t* res, const size_t res_len, const uint8_t sec_hdr_type) {
byte_buffer_t *pdu = pool_allocate_blocking;

Loading…
Cancel
Save