Commit b9e37eb1 authored by Tien Thinh NGUYEN's avatar Tien Thinh NGUYEN

First update 5GSMobileIdentity

parent a0052e37
...@@ -112,6 +112,9 @@ constexpr uint8_t kIeiRejectedNssaiRr = 0x69; ...@@ -112,6 +112,9 @@ constexpr uint8_t kIeiRejectedNssaiRr = 0x69;
constexpr uint8_t kIeiEpsNasMessageContainer = 0x70; constexpr uint8_t kIeiEpsNasMessageContainer = 0x70;
constexpr uint8_t kIeiNasMessageContainer = 0x71; constexpr uint8_t kIeiNasMessageContainer = 0x71;
constexpr uint8_t kIei5gGuti = 0x77; constexpr uint8_t kIei5gGuti = 0x77;
constexpr uint8_t kIeiEapMessage = 0x78; constexpr uint8_t kIeiImeisv = 0x77;
constexpr uint8_t kIeiNonImeisvPei = 0x78;
constexpr uint8_t kIeiEapMessage = 0x78; // TODO: to be verified
constexpr uint8_t kIeiPayloadContainer = constexpr uint8_t kIeiPayloadContainer =
0x7b; // Should be verified (kIeiExtendedProtocolConfigurationOptions) 0x7b; // Should be verified (kIeiExtendedProtocolConfigurationOptions)
This diff is collapsed.
...@@ -22,17 +22,20 @@ ...@@ -22,17 +22,20 @@
#ifndef _5GS_MOBILE_IDENTITY_H_ #ifndef _5GS_MOBILE_IDENTITY_H_
#define _5GS_MOBILE_IDENTITY_H_ #define _5GS_MOBILE_IDENTITY_H_
#include "Type6NasIe.hpp"
#include "struct.hpp"
#include <stdint.h> #include <stdint.h>
#include <optional> #include <optional>
#include "struct.hpp"
extern "C" { extern "C" {
#include "TLVDecoder.h" #include "TLVDecoder.h"
#include "TLVEncoder.h" #include "TLVEncoder.h"
#include "bstrlib.h" #include "bstrlib.h"
} }
constexpr uint8_t k5gMobileIdentityIe5gGutiLength = 14; constexpr uint8_t k5gsMobileIdentityIe5gGutiLength = 11;
constexpr uint8_t k5gsMobileIdentityIe5gSTmsiLength = 7;
constexpr auto k5gsMobileIdentityIeName = "5GS Mobile Identity";
namespace nas { namespace nas {
...@@ -83,18 +86,17 @@ typedef struct _5G_S_TMSI_s { ...@@ -83,18 +86,17 @@ typedef struct _5G_S_TMSI_s {
// TODO: 5GS mobile identity information element for type of identity "MAC // TODO: 5GS mobile identity information element for type of identity "MAC
// address" // address"
class _5GSMobileIdentity { class _5GSMobileIdentity : public Type6NasIe {
public: public:
_5GSMobileIdentity(); _5GSMobileIdentity();
_5GSMobileIdentity(uint8_t iei); _5GSMobileIdentity(uint8_t iei);
~_5GSMobileIdentity(); ~_5GSMobileIdentity();
// Common // Common
void clear(); void clearIe();
uint8_t getTypeOfIdentity() const { return typeOfIdentity; }; uint8_t getTypeOfIdentity() const { return typeOfIdentity; };
void setIEI(uint8_t iei);
int encode2Buffer(uint8_t* buf, int len); int encode2Buffer(uint8_t* buf, int len);
int decodeFromBuffer(uint8_t* buf, int len, bool is_option); int decodeFromBuffer(uint8_t* buf, int len, bool is_iei);
// 5G GUTI // 5G GUTI
int _5g_guti_decodefrombuffer(uint8_t* buf, int len); int _5g_guti_decodefrombuffer(uint8_t* buf, int len);
...@@ -113,7 +115,6 @@ class _5GSMobileIdentity { ...@@ -113,7 +115,6 @@ class _5GSMobileIdentity {
const std::string& mcc, const std::string& mnc, const std::string& mcc, const std::string& mnc,
const std::string& routing_ind, const uint8_t protection_sch_id, const std::string& routing_ind, const uint8_t protection_sch_id,
const std::string& msin); // TODO: SetSUCI, SUCI and SUPI format IMSI const std::string& msin); // TODO: SetSUCI, SUCI and SUPI format IMSI
void setSuciWithSupiImsi( void setSuciWithSupiImsi(
const std::string& mcc, const std::string& mnc, const std::string& mcc, const std::string& mnc,
const std::string& routing_ind, const uint8_t protection_sch_id, const std::string& routing_ind, const uint8_t protection_sch_id,
...@@ -127,12 +128,12 @@ class _5GSMobileIdentity { ...@@ -127,12 +128,12 @@ class _5GSMobileIdentity {
// TMSI // TMSI
int _5g_s_tmsi_decodefrombuffer(uint8_t* buf, int len); int _5g_s_tmsi_decodefrombuffer(uint8_t* buf, int len);
int _5g_s_tmsi_encode2buffer(uint8_t* buf, int len); int _5g_s_tmsi_encode2buffer(uint8_t* buf, int len);
bool get5G_S_TMSI(
uint16_t& amf_set_id, uint8_t& amf_pointer, std::string& tmsi) const;
void set5G_S_TMSI( void set5G_S_TMSI(
const uint16_t amf_set_id, const uint8_t amf_pointer, const uint16_t amf_set_id, const uint8_t amf_pointer,
const std::string& tmsi); const std::string& tmsi);
bool get5G_S_TMSI(
uint16_t& amf_set_id, uint8_t& amf_pointer, std::string& tmsi) const;
// IMEISV // IMEISV
int imeisv_encode2buffer(uint8_t* buf, int len); int imeisv_encode2buffer(uint8_t* buf, int len);
...@@ -142,8 +143,8 @@ class _5GSMobileIdentity { ...@@ -142,8 +143,8 @@ class _5GSMobileIdentity {
bool getIMEISV(IMEISV_t& imeisv) const; bool getIMEISV(IMEISV_t& imeisv) const;
private: private:
uint8_t iei_; // uint8_t iei_;
uint16_t length; // uint16_t length;
uint8_t typeOfIdentity : 3; uint8_t typeOfIdentity : 3;
std::optional<SUCI_imsi_t> supi_format_imsi; std::optional<SUCI_imsi_t> supi_format_imsi;
......
...@@ -41,7 +41,7 @@ NSSAI::NSSAI(uint8_t iei, const std::vector<struct SNSSAI_s>& nssai) ...@@ -41,7 +41,7 @@ NSSAI::NSSAI(uint8_t iei, const std::vector<struct SNSSAI_s>& nssai)
int length = 0; int length = 0;
S_NSSAIs.assign(nssai.begin(), nssai.end()); S_NSSAIs.assign(nssai.begin(), nssai.end());
for (int i = 0; i < nssai.size(); i++) { for (int i = 0; i < nssai.size(); i++) {
length += (1 + nssai[i].length); // 1 for length of NSSAI[i] length += (1 + nssai[i].length); // 1 for length IE
} }
SetLengthIndicator(length); SetLengthIndicator(length);
SetIeName(kNssaiIeName); SetIeName(kNssaiIeName);
......
...@@ -94,6 +94,7 @@ bool Type4NasIe::ValidateHeader(const int& len) const { ...@@ -94,6 +94,7 @@ bool Type4NasIe::ValidateHeader(const int& len) const {
} }
return true; return true;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int Type4NasIe::Encode(uint8_t* buf, const int& len) { int Type4NasIe::Encode(uint8_t* buf, const int& len) {
if (!Validate(len)) return KEncodeDecodeError; if (!Validate(len)) return KEncodeDecodeError;
...@@ -108,6 +109,21 @@ int Type4NasIe::Encode(uint8_t* buf, const int& len) { ...@@ -108,6 +109,21 @@ int Type4NasIe::Encode(uint8_t* buf, const int& len) {
return encoded_size; return encoded_size;
} }
//------------------------------------------------------------------------------
int Type4NasIe::Encode(uint8_t* buf, const int& len, int& len_pos) {
if (!Validate(len)) return KEncodeDecodeError;
int encoded_size = 0;
uint8_t octet = 0;
if (iei_.has_value()) {
ENCODE_U8(buf + encoded_size, iei_.value(), encoded_size);
}
len_pos = encoded_size;
encoded_size++; // IE len will be encoded later
// ENCODE_U8(buf + encoded_size, li_, encoded_size);
return encoded_size;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int Type4NasIe::Decode(const uint8_t* const buf, const int& len, bool is_iei) { int Type4NasIe::Decode(const uint8_t* const buf, const int& len, bool is_iei) {
if (!ValidateHeader(len)) return KEncodeDecodeError; if (!ValidateHeader(len)) return KEncodeDecodeError;
......
...@@ -42,6 +42,9 @@ class Type4NasIe : public NasIe { ...@@ -42,6 +42,9 @@ class Type4NasIe : public NasIe {
uint8_t GetHeaderLength() const; uint8_t GetHeaderLength() const;
int Encode(uint8_t* buf, const int& len) override; int Encode(uint8_t* buf, const int& len) override;
int Encode(
uint8_t* buf, const int& len,
int& len_pos); // Use this function to encode IE lengh later
int Decode( int Decode(
const uint8_t* const buf, const int& len, bool is_iei = false) override; const uint8_t* const buf, const int& len, bool is_iei = false) override;
......
...@@ -35,6 +35,7 @@ Type6NasIe::Type6NasIe() : NasIe() { ...@@ -35,6 +35,7 @@ Type6NasIe::Type6NasIe() : NasIe() {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Type6NasIe::Type6NasIe(const uint8_t& iei) : NasIe() { Type6NasIe::Type6NasIe(const uint8_t& iei) : NasIe() {
iei_ = std::optional<uint8_t>(iei); iei_ = std::optional<uint8_t>(iei);
li_ = 0;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -45,14 +46,101 @@ void Type6NasIe::SetIei(const uint8_t& iei) { ...@@ -45,14 +46,101 @@ void Type6NasIe::SetIei(const uint8_t& iei) {
iei_ = std::optional<uint8_t>(iei); iei_ = std::optional<uint8_t>(iei);
} }
//------------------------------------------------------------------------------
void Type6NasIe::SetLengthIndicator(const uint16_t& li) {
li_ = li;
}
//------------------------------------------------------------------------------
void Type6NasIe::GetLengthIndicator(uint16_t& li) const {
li = li_;
}
//------------------------------------------------------------------------------
uint16_t Type6NasIe::GetLengthIndicator() const {
return li_;
}
//------------------------------------------------------------------------------
uint16_t Type6NasIe::GetIeLength() const {
return (GetHeaderLength() + li_);
}
//------------------------------------------------------------------------------
uint8_t Type6NasIe::GetHeaderLength() const {
return (iei_.has_value() ? 3 : 2); // 1 for IEI, 2 for Length
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool Type6NasIe::Validate(const int& len) const { bool Type6NasIe::Validate(const int& len) const {
uint16_t actual_lengh = iei_.has_value() ? li_ + 1 : li_; uint16_t ie_len = GetIeLength();
if (len < actual_lengh) { if (len < ie_len) {
Logger::nas_mm().error( Logger::nas_mm().error(
"Buffer length is less than the minimum length of this IE (%d octet)", "Buffer length is less than the minimum length of this IE (%d octet)",
actual_lengh); ie_len);
return false; return false;
} }
return true; return true;
} }
//------------------------------------------------------------------------------
bool Type6NasIe::ValidateHeader(const int& len) const {
int header_len = GetHeaderLength(); // Length of IEI/Len
if (len < header_len) {
Logger::nas_mm().error(
"Buffer length is less than the length of the header (IEI/Length) of "
"this IE (%d octet(s))",
header_len);
return false;
}
return true;
}
//------------------------------------------------------------------------------
int Type6NasIe::Encode(uint8_t* buf, const int& len) {
if (!Validate(len)) return KEncodeDecodeError;
int encoded_size = 0;
uint8_t octet = 0;
if (iei_.has_value()) {
ENCODE_U8(buf + encoded_size, iei_.value(), encoded_size);
}
ENCODE_U16(buf + encoded_size, li_, encoded_size);
return encoded_size;
}
//------------------------------------------------------------------------------
int Type6NasIe::Encode(uint8_t* buf, const int& len, int& len_pos) {
if (!Validate(len)) return KEncodeDecodeError;
int encoded_size = 0;
uint8_t octet = 0;
if (iei_.has_value()) {
ENCODE_U8(buf + encoded_size, iei_.value(), encoded_size);
}
len_pos = encoded_size;
encoded_size += sizeof(uint16_t);
// ENCODE_U16(buf + encoded_size, li_, encoded_size);
return encoded_size;
}
//------------------------------------------------------------------------------
int Type6NasIe::Decode(const uint8_t* const buf, const int& len, bool is_iei) {
if (!ValidateHeader(len)) return KEncodeDecodeError;
int decoded_size = 0;
uint8_t octet = 0;
if (is_iei) {
DECODE_U8(buf + decoded_size, octet, decoded_size);
iei_ = std::optional<uint8_t>(octet);
}
DECODE_U16(buf + decoded_size, li_, decoded_size);
// after obtaining information for IEI/Length, validate the buffer size
if (!Validate(len)) return KEncodeDecodeError;
return decoded_size;
}
...@@ -32,10 +32,19 @@ class Type6NasIe : public NasIe { ...@@ -32,10 +32,19 @@ class Type6NasIe : public NasIe {
virtual ~Type6NasIe(); virtual ~Type6NasIe();
bool Validate(const int& len) const override; bool Validate(const int& len) const override;
bool ValidateHeader(const int& len) const;
void SetIei(const uint8_t& iei); void SetIei(const uint8_t& iei);
void SetLengthIndicator(const uint16_t& li);
void GetLengthIndicator(uint16_t& li) const;
uint16_t GetLengthIndicator() const;
uint16_t GetIeLength() const;
uint8_t GetHeaderLength() const;
int Encode(uint8_t* buf, const int& len) override; int Encode(uint8_t* buf, const int& len) override;
int Encode(
uint8_t* buf, const int& len,
int& len_pos); // Use this function to encode IE lengh later
int Decode( int Decode(
const uint8_t* const buf, const int& len, bool is_iei = false) override; const uint8_t* const buf, const int& len, bool is_iei = false) override;
......
...@@ -92,7 +92,7 @@ void RegistrationAccept::setSUCI_SUPI_format_IMSI( ...@@ -92,7 +92,7 @@ void RegistrationAccept::setSUCI_SUPI_format_IMSI(
return; return;
} else { } else {
_5GSMobileIdentity ie_5g_guti_tmp = {}; _5GSMobileIdentity ie_5g_guti_tmp = {};
ie_5g_guti_tmp.setIEI(kIei5gGuti); ie_5g_guti_tmp.SetIei(kIei5gGuti);
ie_5g_guti_tmp.setSuciWithSupiImsi( ie_5g_guti_tmp.setSuciWithSupiImsi(
mcc, mnc, routingInd, protection_sch_id, msin); mcc, mnc, routingInd, protection_sch_id, msin);
ie_5g_guti = std::optional<_5GSMobileIdentity>(ie_5g_guti_tmp); ie_5g_guti = std::optional<_5GSMobileIdentity>(ie_5g_guti_tmp);
...@@ -116,7 +116,7 @@ void RegistrationAccept::set5G_GUTI( ...@@ -116,7 +116,7 @@ void RegistrationAccept::set5G_GUTI(
int regionId = fromString<int>(amfRegionId); int regionId = fromString<int>(amfRegionId);
int setId = fromString<int>(amfSetId); int setId = fromString<int>(amfSetId);
int pointer = fromString<int>(amfPointer); int pointer = fromString<int>(amfPointer);
ie_5g_guti_tmp.setIEI(kIei5gGuti); ie_5g_guti_tmp.SetIei(kIei5gGuti);
ie_5g_guti_tmp.set5GGUTI( ie_5g_guti_tmp.set5GGUTI(
mcc, mnc, (uint8_t) regionId, (uint16_t) setId, (uint8_t) pointer, tmsi); mcc, mnc, (uint8_t) regionId, (uint16_t) setId, (uint8_t) pointer, tmsi);
ie_5g_guti = std::optional<_5GSMobileIdentity>(ie_5g_guti_tmp); ie_5g_guti = std::optional<_5GSMobileIdentity>(ie_5g_guti_tmp);
......
...@@ -136,7 +136,7 @@ void RegistrationRequest::setAdditional_GUTI_SUCI_SUPI_format_IMSI( ...@@ -136,7 +136,7 @@ void RegistrationRequest::setAdditional_GUTI_SUCI_SUPI_format_IMSI(
const string mcc, const string mnc, uint8_t amf_region_id, const string mcc, const string mnc, uint8_t amf_region_id,
uint8_t amf_set_id, uint8_t amf_pointer, const string _5g_tmsi) { uint8_t amf_set_id, uint8_t amf_pointer, const string _5g_tmsi) {
_5GSMobileIdentity ie_additional_guti_tmp = {}; _5GSMobileIdentity ie_additional_guti_tmp = {};
ie_additional_guti_tmp.setIEI(0x77); ie_additional_guti_tmp.SetIei(kIei5gGuti);
uint32_t tmsi = fromString<uint32_t>(_5g_tmsi); uint32_t tmsi = fromString<uint32_t>(_5g_tmsi);
ie_additional_guti_tmp.set5GGUTI( ie_additional_guti_tmp.set5GGUTI(
mcc, mnc, amf_region_id, amf_set_id, amf_pointer, tmsi); mcc, mnc, amf_region_id, amf_set_id, amf_pointer, tmsi);
......
...@@ -160,8 +160,8 @@ class RegistrationRequest : public NasMmPlainHeader { ...@@ -160,8 +160,8 @@ class RegistrationRequest : public NasMmPlainHeader {
std::optional<UplinkDataStatus> ie_uplink_data_status; // Optional std::optional<UplinkDataStatus> ie_uplink_data_status; // Optional
std::optional<PDUSessionStatus> ie_PDU_session_status; // Optional std::optional<PDUSessionStatus> ie_PDU_session_status; // Optional
std::optional<MicoIndication> ie_MICO_indication; // Optional std::optional<MicoIndication> ie_MICO_indication; // Optional
std::optional<UEStatus> ie_ue_status; // Optional std::optional<UEStatus> ie_ue_status; // Optional
std::optional<_5GSMobileIdentity> ie_additional_guti; // Optional std::optional<_5GSMobileIdentity> ie_additional_guti; // Optional
std::optional<AllowedPDUSessionStatus> std::optional<AllowedPDUSessionStatus>
ie_allowed_PDU_session_status; // Optional ie_allowed_PDU_session_status; // Optional
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "SecurityModeComplete.hpp" #include "SecurityModeComplete.hpp"
#include "3gpp_24.501.hpp" #include "3gpp_24.501.hpp"
#include "Ie_Const.hpp"
#include "logger.hpp" #include "logger.hpp"
using namespace nas; using namespace nas;
...@@ -55,7 +56,7 @@ void SecurityModeComplete::setHeader(uint8_t security_header_type) { ...@@ -55,7 +56,7 @@ void SecurityModeComplete::setHeader(uint8_t security_header_type) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void SecurityModeComplete::setIMEISV(IMEISV_t imeisv) { void SecurityModeComplete::setIMEISV(IMEISV_t imeisv) {
ie_imeisv = new _5GSMobileIdentity(); ie_imeisv = new _5GSMobileIdentity();
ie_imeisv->setIEI(0x77); ie_imeisv->SetIei(kIeiImeisv);
ie_imeisv->setIMEISV(imeisv); ie_imeisv->setIMEISV(imeisv);
} }
...@@ -67,7 +68,7 @@ void SecurityModeComplete::setNAS_Message_Container(bstring value) { ...@@ -67,7 +68,7 @@ void SecurityModeComplete::setNAS_Message_Container(bstring value) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void SecurityModeComplete::setNON_IMEISV(IMEISV_t imeisv) { void SecurityModeComplete::setNON_IMEISV(IMEISV_t imeisv) {
ie_non_imeisvpei = new _5GSMobileIdentity(); ie_non_imeisvpei = new _5GSMobileIdentity();
ie_non_imeisvpei->setIEI(0x78); ie_non_imeisvpei->SetIei(kIeiNonImeisvPei);
ie_non_imeisvpei->setIMEISV(imeisv); ie_non_imeisvpei->setIMEISV(imeisv);
} }
......
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