Commit 560c1dfb authored by Tien Thinh NGUYEN's avatar Tien Thinh NGUYEN

Update Deregistration Request (UE originating)

parent 2db5addf
...@@ -3011,8 +3011,9 @@ void amf_n1::ue_initiate_de_registration_handle( ...@@ -3011,8 +3011,9 @@ void amf_n1::ue_initiate_de_registration_handle(
} }
// Decode NAS message // Decode NAS message
auto dereg_request = std::make_unique<DeregistrationRequest>(); auto dereg_request = std::make_unique<DeregistrationRequest>(
dereg_request->Decode(NULL, (uint8_t*) bdata(nas), blength(nas)); true); // UE originating de-registration
dereg_request->Decode((uint8_t*) bdata(nas), blength(nas));
// TODO: validate 5G Mobile Identity // TODO: validate 5G Mobile Identity
uint8_t mobile_id_type = 0; uint8_t mobile_id_type = 0;
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include "Type1NasIeFormatTv.hpp" #include "Type1NasIeFormatTv.hpp"
#include <stdint.h>
constexpr auto k5gsRegistrationTypeName = "5GS Registration Type"; constexpr auto k5gsRegistrationTypeName = "5GS Registration Type";
namespace nas { namespace nas {
......
...@@ -18,14 +18,6 @@ ...@@ -18,14 +18,6 @@
* For more information about the OpenAirInterface (OAI) Software Alliance: * For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*! \file
\brief
\author
\date 2020
\email: contact@openairinterface.org
*/
#include "_5GSDeregistrationType.hpp" #include "_5GSDeregistrationType.hpp"
#include "3gpp_24.501.hpp" #include "3gpp_24.501.hpp"
...@@ -34,13 +26,23 @@ ...@@ -34,13 +26,23 @@
using namespace nas; using namespace nas;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
_5GSDeregistrationType::_5GSDeregistrationType() { _5GSDeregistrationType::_5GSDeregistrationType() : Type1NasIeFormatTv() {
u1.b = 0; u1.b = 0;
SetIeName(k5gsDeregistrationTypeIeName);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
_5GSDeregistrationType::_5GSDeregistrationType(uint8_t type) { _5GSDeregistrationType::_5GSDeregistrationType(uint8_t iei)
u1.b = type; : Type1NasIeFormatTv(iei) {
u1.bf.iei = iei;
SetIeName(k5gsDeregistrationTypeIeName);
}
//------------------------------------------------------------------------------
_5GSDeregistrationType::_5GSDeregistrationType(uint8_t iei, uint8_t value) {
u1.b = (iei << 4) | (value && 0x0f);
SetValue(value && 0x0f);
SetIeName(k5gsDeregistrationTypeIeName);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
_5GSDeregistrationType::_5GSDeregistrationType( _5GSDeregistrationType::_5GSDeregistrationType(
...@@ -50,11 +52,29 @@ _5GSDeregistrationType::_5GSDeregistrationType( ...@@ -50,11 +52,29 @@ _5GSDeregistrationType::_5GSDeregistrationType(
u1.bf.re_registration_required = type.re_registration_required; u1.bf.re_registration_required = type.re_registration_required;
u1.bf.access_type = type.access_type; u1.bf.access_type = type.access_type;
u1.bf.iei = type.iei; u1.bf.iei = type.iei;
if (type.iei != 0) {
SetIei(type.iei);
}
SetValue(u1.b && 0x0f);
SetIeName(k5gsDeregistrationTypeIeName);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
_5GSDeregistrationType::~_5GSDeregistrationType() {} _5GSDeregistrationType::~_5GSDeregistrationType() {}
//------------------------------------------------------------------------------
void _5GSDeregistrationType::setValue() {
Type1NasIeFormatTv::SetValue(u1.b && 0x0f);
}
//------------------------------------------------------------------------------
void _5GSDeregistrationType::getValue() {
u1.b = Type1NasIeFormatTv::GetValue() && 0x0f;
if (iei_.has_value()) {
u1.b |= iei_.value() && 0xf0;
}
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void _5GSDeregistrationType::set(_5gs_deregistration_type_t type) { void _5GSDeregistrationType::set(_5gs_deregistration_type_t type) {
u1.b = 0; u1.b = 0;
...@@ -62,6 +82,10 @@ void _5GSDeregistrationType::set(_5gs_deregistration_type_t type) { ...@@ -62,6 +82,10 @@ void _5GSDeregistrationType::set(_5gs_deregistration_type_t type) {
u1.bf.re_registration_required = type.re_registration_required; u1.bf.re_registration_required = type.re_registration_required;
u1.bf.access_type = type.access_type; u1.bf.access_type = type.access_type;
u1.bf.iei = type.iei; u1.bf.iei = type.iei;
if (type.iei != 0) {
SetIei(type.iei);
}
SetValue(u1.b && 0x0f);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -82,6 +106,7 @@ void _5GSDeregistrationType::get(uint8_t& type) { ...@@ -82,6 +106,7 @@ void _5GSDeregistrationType::get(uint8_t& type) {
type = u1.b; type = u1.b;
} }
/*
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int _5GSDeregistrationType::Encode(uint8_t* buf, int len) { int _5GSDeregistrationType::Encode(uint8_t* buf, int len) {
Logger::nas_mm().error("Encoding 5GSDeregistrationType IE"); Logger::nas_mm().error("Encoding 5GSDeregistrationType IE");
...@@ -102,3 +127,4 @@ int _5GSDeregistrationType::Decode(uint8_t* buf, int len) { ...@@ -102,3 +127,4 @@ int _5GSDeregistrationType::Decode(uint8_t* buf, int len) {
Logger::nas_mm().debug("Decoded 5GSDeRegistrationType"); Logger::nas_mm().debug("Decoded 5GSDeRegistrationType");
return 0; return 0;
} }
*/
...@@ -19,17 +19,10 @@ ...@@ -19,17 +19,10 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*! \file
\brief
\author
\date 2020
\email: contact@openairinterface.org
*/
#ifndef _5GS_DEREGISTRATION_TYPE_H_ #ifndef _5GS_DEREGISTRATION_TYPE_H_
#define _5GS_DEREGISTRATION_TYPE_H_ #define _5GS_DEREGISTRATION_TYPE_H_
#include <stdint.h> #include "Type1NasIeFormatTv.hpp"
namespace nas { namespace nas {
typedef struct _5gs_deregistration_type_s { typedef struct _5gs_deregistration_type_s {
...@@ -39,21 +32,32 @@ typedef struct _5gs_deregistration_type_s { ...@@ -39,21 +32,32 @@ typedef struct _5gs_deregistration_type_s {
uint8_t access_type : 2; uint8_t access_type : 2;
} _5gs_deregistration_type_t; } _5gs_deregistration_type_t;
class _5GSDeregistrationType { constexpr auto k5gsDeregistrationTypeIeName = "5GS De-registration Type";
class _5GSDeregistrationType : public Type1NasIeFormatTv {
public: public:
_5GSDeregistrationType(); _5GSDeregistrationType();
_5GSDeregistrationType(uint8_t type); _5GSDeregistrationType(uint8_t iei);
_5GSDeregistrationType(uint8_t iei, uint8_t value);
_5GSDeregistrationType(_5gs_deregistration_type_t type); _5GSDeregistrationType(_5gs_deregistration_type_t type);
~_5GSDeregistrationType(); ~_5GSDeregistrationType();
int Decode(uint8_t* buf, int len);
int Encode(uint8_t* buf, int len); // int Decode(uint8_t* buf, int len);
// int Encode(uint8_t* buf, int len);
void set(_5gs_deregistration_type_t type); void set(_5gs_deregistration_type_t type);
void get(_5gs_deregistration_type_t& type); void get(_5gs_deregistration_type_t& type);
void set(uint8_t type);
void get(uint8_t& type);
public: void set(uint8_t value);
void get(uint8_t& value);
void set(uint8_t iei, uint8_t value);
void get(uint8_t& iei, uint8_t value);
private:
void setValue();
void getValue();
union { union {
struct { struct {
uint8_t iei : 4; uint8_t iei : 4;
......
...@@ -19,13 +19,6 @@ ...@@ -19,13 +19,6 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*! \file
\brief
\author
\date 2020
\email: contact@openairinterface.org
*/
#include "DeregistrationRequest.hpp" #include "DeregistrationRequest.hpp"
#include <string> #include <string>
...@@ -38,11 +31,13 @@ ...@@ -38,11 +31,13 @@
using namespace nas; using namespace nas;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
DeregistrationRequest::DeregistrationRequest() { DeregistrationRequest::DeregistrationRequest(bool is_ue_originating)
plain_header = nullptr; : NasMmPlainHeader(EPD_5GS_MM_MSG) {
ie_deregistrationtype = nullptr; if (is_ue_originating) {
ie_ngKSI = nullptr; NasMmPlainHeader::SetMessageType(DEREGISTRATION_REQUEST_UE_ORIGINATING);
ie_5gs_mobility_id = nullptr; } else {
NasMmPlainHeader::SetMessageType(DEREGISTRATION_REQUEST_UE_TERMINATED);
}
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -50,50 +45,43 @@ DeregistrationRequest::~DeregistrationRequest() {} ...@@ -50,50 +45,43 @@ DeregistrationRequest::~DeregistrationRequest() {}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void DeregistrationRequest::SetHeader(uint8_t security_header_type) { void DeregistrationRequest::SetHeader(uint8_t security_header_type) {
plain_header = new NasMmPlainHeader(); NasMmPlainHeader::SetSecurityHeaderType(security_header_type);
plain_header->SetHeader(
EPD_5GS_MM_MSG, security_header_type,
DEREGISTRATION_REQUEST_UE_ORIGINATING);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void DeregistrationRequest::setDeregistrationType(uint8_t dereg_type) { void DeregistrationRequest::setDeregistrationType(uint8_t dereg_type) {
ie_deregistrationtype = new _5GSDeregistrationType(dereg_type); ie_deregistrationtype.set(dereg_type);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void DeregistrationRequest::setDeregistrationType( void DeregistrationRequest::setDeregistrationType(
_5gs_deregistration_type_t type) { _5gs_deregistration_type_t type) {
ie_deregistrationtype = new _5GSDeregistrationType(type); ie_deregistrationtype.set(type);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void DeregistrationRequest::SetNgKsi(uint8_t tsc, uint8_t key_set_id) { void DeregistrationRequest::SetNgKsi(uint8_t tsc, uint8_t key_set_id) {
ie_ngKSI = new NasKeySetIdentifier(tsc, key_set_id); ie_ngKSI.Set(true); // high position
ie_ngKSI->Set(true); // high position ie_ngKSI.SetTypeOfSecurityContext(tsc);
ie_ngKSI.SetNasKeyIdentifier(key_set_id);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void DeregistrationRequest::getDeregistrationType(uint8_t& dereg_type) { void DeregistrationRequest::getDeregistrationType(uint8_t& dereg_type) {
if (ie_deregistrationtype) ie_deregistrationtype->get(dereg_type); ie_deregistrationtype.get(dereg_type);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void DeregistrationRequest::getDeregistrationType( void DeregistrationRequest::getDeregistrationType(
_5gs_deregistration_type_t& type) { _5gs_deregistration_type_t& type) {
if (ie_deregistrationtype) ie_deregistrationtype->get(type); ie_deregistrationtype.get(type);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool DeregistrationRequest::getngKSI(uint8_t& ng_ksi) { bool DeregistrationRequest::getngKSI(uint8_t& ng_ksi) {
if (ie_ngKSI) { ng_ksi =
ng_ksi = (ie_ngKSI->GetTypeOfSecurityContext()) | (ie_ngKSI.GetTypeOfSecurityContext()) | ie_ngKSI.GetNasKeyIdentifier();
ie_ngKSI->GetNasKeyIdentifier();
return true; return true;
} else {
// ng_ksi = 0;
return false;
}
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -106,36 +94,26 @@ void DeregistrationRequest::SetSuciSupiFormatImsi( ...@@ -106,36 +94,26 @@ void DeregistrationRequest::SetSuciSupiFormatImsi(
"protection scheme"); "protection scheme");
return; return;
} else { } else {
ie_5gs_mobility_id = new _5GSMobileIdentity(); ie_5gs_mobility_id.SetSuciWithSupiImsi(
ie_5gs_mobility_id->SetSuciWithSupiImsi(
mcc, mnc, routingInd, protection_sch_id, msin); mcc, mnc, routingInd, protection_sch_id, msin);
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void DeregistrationRequest::getMobilityIdentityType(uint8_t& type) { void DeregistrationRequest::getMobilityIdentityType(uint8_t& type) {
if (ie_5gs_mobility_id) { type = ie_5gs_mobility_id.GetTypeOfIdentity();
type = ie_5gs_mobility_id->GetTypeOfIdentity();
} else {
type = 0;
}
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool DeregistrationRequest::getSuciSupiFormatImsi(nas::SUCI_imsi_t& imsi) { bool DeregistrationRequest::getSuciSupiFormatImsi(nas::SUCI_imsi_t& imsi) {
if (ie_5gs_mobility_id) { ie_5gs_mobility_id.GetSuciWithSupiImsi(imsi);
ie_5gs_mobility_id->GetSuciWithSupiImsi(imsi);
return true; return true;
} else {
return false;
}
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
std::string DeregistrationRequest::get_5g_guti() { std::string DeregistrationRequest::get_5g_guti() {
if (ie_5gs_mobility_id) {
std::optional<nas::_5G_GUTI_t> guti = std::nullopt; std::optional<nas::_5G_GUTI_t> guti = std::nullopt;
ie_5gs_mobility_id->Get5gGuti(guti); ie_5gs_mobility_id.Get5gGuti(guti);
if (!guti.has_value()) return {}; if (!guti.has_value()) return {};
std::string guti_str = guti.value().mcc + guti.value().mnc + std::string guti_str = guti.value().mcc + guti.value().mnc +
...@@ -145,9 +123,6 @@ std::string DeregistrationRequest::get_5g_guti() { ...@@ -145,9 +123,6 @@ std::string DeregistrationRequest::get_5g_guti() {
conv::tmsi_to_string(guti.value()._5g_tmsi); conv::tmsi_to_string(guti.value()._5g_tmsi);
Logger::nas_mm().debug("5G GUTI %s", guti_str.c_str()); Logger::nas_mm().debug("5G GUTI %s", guti_str.c_str());
return guti_str; return guti_str;
} else {
return {};
}
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -167,69 +142,86 @@ void DeregistrationRequest::Set5gSTmsi() {} ...@@ -167,69 +142,86 @@ void DeregistrationRequest::Set5gSTmsi() {}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int DeregistrationRequest::Encode(uint8_t* buf, int len) { int DeregistrationRequest::Encode(uint8_t* buf, int len) {
Logger::nas_mm().debug("Encoding DeregistrationRequest message"); Logger::nas_mm().debug("Encoding DeregistrationRequest message");
int encoded_size = 0; int encoded_size = 0;
if (!plain_header) { int encoded_ie_size = 0;
Logger::nas_mm().error("Mandatory IE missing Header");
return 0; // Header
} if ((encoded_ie_size = NasMmPlainHeader::Encode(buf, len)) ==
if (!ie_deregistrationtype) { KEncodeDecodeError) {
Logger::nas_mm().error("Mandatory IE missing Deregistration Type"); Logger::nas_mm().error("Encoding NAS Header error");
return 0; return KEncodeDecodeError;
} }
if (!ie_ngKSI) { encoded_size += encoded_ie_size;
Logger::nas_mm().error("Mandatory IE missing ie_ngKSI");
return 0; // De-registration Type and ngKSI
int size =
ie_deregistrationtype.Encode(buf + encoded_size, len - encoded_size);
if (size == KEncodeDecodeError) {
Logger::nas_mm().error("Encoding ie_deregistrationtype error");
return KEncodeDecodeError;
} }
if (!ie_5gs_mobility_id) { if (size != 0) {
Logger::nas_mm().error("Mandatory IE missing ie_5gs_mobility_id"); Logger::nas_mm().error("Encoding ie_deregistrationtype error");
return 0; return KEncodeDecodeError;
}
if (!(plain_header->Encode(buf, len))) return 0;
encoded_size += 3;
if (!(ie_deregistrationtype->Encode(
buf + encoded_size, len - encoded_size))) {
if (ie_ngKSI->Encode(buf + encoded_size, len - encoded_size) !=
KEncodeDecodeError) {
encoded_size += 1; // 1/2 octet for Deregistration Request, 1/2 for ngKSI
} else {
Logger::nas_mm().error("Encoding IE ie_ngKSI error");
return 0;
} }
size = ie_ngKSI.Encode(buf + encoded_size, len - encoded_size);
if (size != KEncodeDecodeError) {
encoded_size++; // 1/2 octet for Deregistration Type, 1/2 for ngKSI
} else { } else {
Logger::nas_mm().error("Encoding IE Deregistration Type error"); Logger::nas_mm().error("Encoding ie_service_type error");
return 0; return KEncodeDecodeError;
} }
if (int size =
ie_5gs_mobility_id->Encode(buf + encoded_size, len - encoded_size)) { // 5GS mobile identity
size = ie_5gs_mobility_id.Encode(buf + encoded_size, len - encoded_size);
if (size != KEncodeDecodeError) {
encoded_size += size; encoded_size += size;
} else { } else {
Logger::nas_mm().error("Encoding IE ie_5gs_mobility_id error"); Logger::nas_mm().error("Encoding IE ie_5gs_mobility_id error");
return 0; return KEncodeDecodeError;
} }
Logger::nas_mm().debug( Logger::nas_mm().debug(
"Encoded DeregistrationRequest message len (%d)", encoded_size); "Encoded DeregistrationRequest message len (%d)", encoded_size);
return 1; return encoded_size;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int DeregistrationRequest::Decode( int DeregistrationRequest::Decode(uint8_t* buf, int len) {
NasMmPlainHeader* header, uint8_t* buf, int len) {
Logger::nas_mm().debug("Decoding DeregistrationRequest message"); Logger::nas_mm().debug("Decoding DeregistrationRequest message");
int decoded_size = 3;
plain_header = header; int decoded_size = 0;
ie_deregistrationtype = new _5GSDeregistrationType(); int decoded_result = 0;
decoded_size +=
ie_deregistrationtype->Decode(buf + decoded_size, len - decoded_size); // Header
ie_ngKSI = new NasKeySetIdentifier(); decoded_result = NasMmPlainHeader::Decode(buf, len);
decoded_size += ie_ngKSI->Decode( if (decoded_result == KEncodeDecodeError) {
buf + decoded_size, len - decoded_size, true, Logger::nas_mm().error("Decoding NAS Header error");
false); // High position, 1/2 octet return KEncodeDecodeError;
decoded_size++; // 1/2 octet for Deregistration type, 1/2 for ngKSI }
ie_5gs_mobility_id = new _5GSMobileIdentity(); decoded_size += decoded_result;
decoded_size +=
ie_5gs_mobility_id->Decode(buf + decoded_size, len - decoded_size, false); // De-registration Type + ngKSI
decoded_result = ie_deregistrationtype.Decode(
buf + decoded_size, len - decoded_size, false);
if (decoded_result == KEncodeDecodeError) return KEncodeDecodeError;
decoded_result = ie_ngKSI.Decode(
buf + decoded_size, len - decoded_size, true, false); // 4 higher bits
if (decoded_result == KEncodeDecodeError) return KEncodeDecodeError;
decoded_size++; // 1/2 octet for De-registration Type, 1/2 ngKSI
decoded_result =
ie_5gs_mobility_id.Decode(buf + decoded_size, len - decoded_size, false);
if (decoded_result == KEncodeDecodeError) {
Logger::nas_mm().error("Decoding 5GS mobile identity error");
return KEncodeDecodeError;
}
decoded_size += decoded_result;
Logger::nas_mm().debug( Logger::nas_mm().debug(
"Decoded DeregistrationRequest message (len %d)", decoded_size); "Decoded DeregistrationRequest message (len %d)", decoded_size);
return 1; return decoded_size;
} }
...@@ -27,13 +27,16 @@ ...@@ -27,13 +27,16 @@
using namespace std; using namespace std;
namespace nas { namespace nas {
class DeregistrationRequest { class DeregistrationRequest : public NasMmPlainHeader {
public: public:
DeregistrationRequest(); DeregistrationRequest(bool is_ue_originating);
~DeregistrationRequest(); ~DeregistrationRequest();
int Encode(uint8_t* buf, int len); int Encode(uint8_t* buf, int len);
int Decode(NasMmPlainHeader* header, uint8_t* buf, int len); int Decode(uint8_t* buf, int len);
void SetHeader(uint8_t security_header_type); void SetHeader(uint8_t security_header_type);
void setDeregistrationType(uint8_t dereg_type); void setDeregistrationType(uint8_t dereg_type);
void setDeregistrationType(_5gs_deregistration_type_t type); void setDeregistrationType(_5gs_deregistration_type_t type);
void SetNgKsi(uint8_t tsc, uint8_t key_set_id); void SetNgKsi(uint8_t tsc, uint8_t key_set_id);
...@@ -57,10 +60,9 @@ class DeregistrationRequest { ...@@ -57,10 +60,9 @@ class DeregistrationRequest {
bool getSuciSupiFormatImsi(nas::SUCI_imsi_t& imsi); bool getSuciSupiFormatImsi(nas::SUCI_imsi_t& imsi);
public: public:
NasMmPlainHeader* plain_header; _5GSDeregistrationType ie_deregistrationtype; // Mandatory
_5GSDeregistrationType* ie_deregistrationtype; NasKeySetIdentifier ie_ngKSI; // Mandatory
NasKeySetIdentifier* ie_ngKSI; _5GSMobileIdentity ie_5gs_mobility_id; // Mandatory
_5GSMobileIdentity* ie_5gs_mobility_id;
}; };
} // namespace nas } // namespace nas
......
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
using namespace nas; using namespace nas;
//------------------------------------------------------------------------------
NasMmPlainHeader::NasMmPlainHeader(const uint8_t& epd) : epd_(epd) {}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
NasMmPlainHeader::NasMmPlainHeader(const uint8_t& epd, const uint8_t& msg_type) NasMmPlainHeader::NasMmPlainHeader(const uint8_t& epd, const uint8_t& msg_type)
: epd_(epd), msg_type_(msg_type) {} : epd_(epd), msg_type_(msg_type) {}
......
...@@ -33,6 +33,7 @@ namespace nas { ...@@ -33,6 +33,7 @@ namespace nas {
class NasMmPlainHeader { class NasMmPlainHeader {
public: public:
NasMmPlainHeader(){}; NasMmPlainHeader(){};
NasMmPlainHeader(const uint8_t& epd);
NasMmPlainHeader(const uint8_t& epd, const uint8_t& msg_type); NasMmPlainHeader(const uint8_t& epd, const uint8_t& msg_type);
virtual ~NasMmPlainHeader(); virtual ~NasMmPlainHeader();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment