Commit 9d8b594d authored by Tien Thinh NGUYEN's avatar Tien Thinh NGUYEN

Code refactor for PLMN List

parent 4ad2b4f6
......@@ -3945,7 +3945,7 @@ void amf_n1::get_pdu_session_to_be_activated(
void amf_n1::initialize_registration_accept(
std::unique_ptr<nas::RegistrationAccept>& registration_accept) {
registration_accept->setHeader(PLAIN_5GS_MSG);
registration_accept->set_5GS_Registration_Result(
registration_accept->set5GSRegistrationResult(
false, false, false,
0x01); // 3GPP Access
registration_accept->setT3512_Value(0x5, T3512_TIMER_VALUE_MIN);
......@@ -3987,7 +3987,7 @@ void amf_n1::initialize_registration_accept(
std::unique_ptr<nas::RegistrationAccept>& registration_accept,
const std::shared_ptr<nas_context>& nc) {
registration_accept->setHeader(PLAIN_5GS_MSG);
registration_accept->set_5GS_Registration_Result(
registration_accept->set5GSRegistrationResult(
false, false, false,
0x01); // 3GPP Access
registration_accept->setT3512_Value(0x5, T3512_TIMER_VALUE_MIN);
......
......@@ -87,6 +87,8 @@ constexpr uint8_t kIeiNetworkSlicingIndication = 0x09; // 9-(4 higher bits)
constexpr uint8_t kT3502Value = 0x16;
constexpr uint8_t kEquivalentPlmns = 0x4A;
constexpr uint8_t kIei5gsUpdateType = 0x53;
constexpr uint8_t kT3346Value = 0x5f;
......@@ -95,6 +97,7 @@ constexpr uint8_t kIeiRejectedNssaiRr = 0x69;
constexpr uint8_t kIeiEpsNasMessageContainer = 0x70;
constexpr uint8_t kIeiNasMessageContainer = 0x71;
constexpr uint8_t kIei5gGuti = 0x77;
constexpr uint8_t kIeiEapMessage = 0x78;
constexpr uint8_t kIeiPayloadContainer =
0x7b; // Should be verified (kIeiExtendedProtocolConfigurationOptions)
......@@ -19,128 +19,93 @@
* contact@openairinterface.org
*/
/*! \file
\brief
\author Keliang DU, BUPT
\date 2020
\email: contact@openairinterface.org
*/
#include "PLMN_List.hpp"
#include "3gpp_24.501.hpp"
#include "common_defs.h"
#include "logger.hpp"
#include "NasUtils.hpp"
using namespace nas;
//------------------------------------------------------------------------------
PLMN_List::PLMN_List(uint8_t iei) {
_iei = iei;
_MNC_MCC1 = 0;
_MNC_MCC2 = 0;
_MNC_MCC3 = 0;
}
//------------------------------------------------------------------------------
PLMN_List::PLMN_List(
const uint8_t iei, uint8_t MNC_MCC1, uint8_t MNC_MCC2, uint8_t MNC_MCC3) {
_iei = iei;
_MNC_MCC1 = MNC_MCC1;
_MNC_MCC2 = MNC_MCC2;
_MNC_MCC3 = MNC_MCC3;
_iei = iei;
length = 2;
}
//------------------------------------------------------------------------------
PLMN_List::PLMN_List() {
_iei = 0;
_MNC_MCC1 = 0;
_MNC_MCC2 = 0;
_MNC_MCC3 = 0;
_iei = 0;
length = 2;
}
//------------------------------------------------------------------------------
PLMN_List::~PLMN_List() {}
//------------------------------------------------------------------------------
void PLMN_List::setMNC_MCC1(uint8_t iei, uint8_t value) {
void PLMN_List::set(uint8_t iei, const std::vector<nas_plmn_t>& list) {
_iei = iei;
_MNC_MCC1 = value;
plmn_list = list;
if (list.size() > 0)
length =
kPlmnListMinimumLength +
(list.size() - 1) *
3; // 3 - size of each PLMN
// size of the first PLMN is included in kPlmnListMinimumLength
}
//------------------------------------------------------------------------------
void PLMN_List::setMNC_MCC2(uint8_t iei, uint8_t value) {
_iei = iei;
_MNC_MCC2 = value;
}
//------------------------------------------------------------------------------
void PLMN_List::setMNC_MCC3(uint8_t iei, uint8_t value) {
_iei = iei;
_MNC_MCC3 = value;
}
//------------------------------------------------------------------------------
uint8_t PLMN_List::getMNC_MCC1() {
return _MNC_MCC1;
}
//------------------------------------------------------------------------------
uint8_t PLMN_List::getMNC_MCC2() {
return _MNC_MCC2;
}
//------------------------------------------------------------------------------
uint8_t PLMN_List::getMNC_MCC3() {
return _MNC_MCC3;
void PLMN_List::getPLMNList(std::vector<nas_plmn_t>& list) {
list = plmn_list;
}
//------------------------------------------------------------------------------
int PLMN_List::encode2Buffer(uint8_t* buf, int len) {
Logger::nas_mm().debug("encoding PLMN_List iei(0x%x)", _iei);
if (len < 5) {
Logger::nas_mm().error("len is less than 5");
return 0;
Logger::nas_mm().debug("Encoding PLMN_List");
if (len < length) {
Logger::nas_mm().error(
"Buffer length is less than the length of this IE (%d octet)", length);
return KEncodeDecodeError;
}
int encoded_size = 0;
if (_iei) {
*(buf + encoded_size) = _iei;
encoded_size++;
*(buf + encoded_size) = 3;
encoded_size++;
*(buf + encoded_size) = (_MNC_MCC1 & 0x0F) | ((_MNC_MCC2 & 0x0F) << 4);
encoded_size++;
*(buf + encoded_size) = _MNC_MCC3;
encoded_size++;
*(buf + encoded_size) = ((_MNC_MCC1 & 0xF0) >> 4) | (_MNC_MCC2 & 0xF0);
encoded_size++;
} else {
// *(buf + encoded_size) = length - 1; encoded_size++;
// *(buf + encoded_size) = _value; encoded_size++; encoded_size++;
ENCODE_U8(buf + encoded_size, _iei, encoded_size); // IEI
}
Logger::nas_mm().debug("encoded PLMN_List len(%d)", encoded_size);
// Length
ENCODE_U8(buf + encoded_size, length, encoded_size);
for (auto it : plmn_list)
encoded_size += NasUtils::encodeMccMnc2Buffer(
it.mcc, it.mnc, buf + encoded_size, len - encoded_size);
Logger::nas_mm().debug("Encoded PLMN_List (len %d)", encoded_size);
return encoded_size;
}
//------------------------------------------------------------------------------
int PLMN_List::decodeFromBuffer(uint8_t* buf, int len, bool is_option) {
Logger::nas_mm().debug("decoding PLMN_List iei(0x%x)", *buf);
Logger::nas_mm().debug("Decoding PLMN_List");
int decoded_size = 0;
if (is_option) {
decoded_size++;
DECODE_U8(buf + decoded_size, _iei, decoded_size); // IEI
}
// Length
DECODE_U8(buf + decoded_size, length, decoded_size);
uint8_t len_ie = length;
while (len_ie > 0) {
nas_plmn_t nas_plmn = {};
uint8_t size = NasUtils::decodeMccMncFromBuffer(
nas_plmn.mcc, nas_plmn.mnc, buf + decoded_size, len - decoded_size);
if (size > 0) {
len_ie -= size;
plmn_list.push_back(nas_plmn);
} else {
break;
}
}
decoded_size++;
_MNC_MCC1 = 0x00;
_MNC_MCC2 = 0x00;
_MNC_MCC3 = 0x00;
_MNC_MCC1 |= *(buf + decoded_size) & 0x0F;
_MNC_MCC2 |= (*(buf + decoded_size) & 0xF0) >> 4;
decoded_size++;
_MNC_MCC3 = *(buf + decoded_size);
decoded_size++;
_MNC_MCC1 |= (*(buf + decoded_size) & 0x0F) << 4;
_MNC_MCC2 |= *(buf + decoded_size) & 0xF0;
decoded_size++;
Logger::nas_mm().debug(
"decoded PLMN_List MNC_MCC1(0x%x),MNC_MCC2(0x%x),MNC_MCC3(0x%x)",
_MNC_MCC1, _MNC_MCC2, _MNC_MCC3);
Logger::nas_mm().debug("decoded PLMN_List len(%d)", decoded_size);
Logger::nas_mm().debug("Decoded PLMN_List (len %d)", decoded_size);
return decoded_size;
}
......@@ -19,17 +19,15 @@
* contact@openairinterface.org
*/
/*! \file
\brief
\author Keliang DU, BUPT
\date 2020
\email: contact@openairinterface.org
*/
#ifndef __PLMN_List_H_
#define __PLMN_List_H_
#ifndef _PLMN_LIST_H_
#define _PLMN_LIST_H_
#include "struct.hpp"
#include <stdint.h>
#include <vector>
constexpr uint8_t kPlmnListMinimumLength = 5;
constexpr uint8_t kPlmnListMaximumLength = 47;
namespace nas {
......@@ -37,23 +35,18 @@ class PLMN_List {
public:
PLMN_List();
PLMN_List(uint8_t iei);
PLMN_List(
const uint8_t iei, uint8_t MNC_MCC1, uint8_t MNC_MCC2, uint8_t MNC_MCC3);
~PLMN_List();
void setMNC_MCC1(uint8_t iei, uint8_t value);
void setMNC_MCC2(uint8_t iei, uint8_t value);
void setMNC_MCC3(uint8_t iei, uint8_t value);
int encode2Buffer(uint8_t* buf, int len);
int decodeFromBuffer(uint8_t* buf, int len, bool is_option);
uint8_t getMNC_MCC1();
uint8_t getMNC_MCC2();
uint8_t getMNC_MCC3();
void set(uint8_t iei, const std::vector<nas_plmn_t>& list);
void getPLMNList(std::vector<nas_plmn_t>& list);
private:
uint8_t _iei;
uint8_t _MNC_MCC1;
uint8_t _MNC_MCC2;
uint8_t _MNC_MCC3;
uint8_t length;
std::vector<nas_plmn_t> plmn_list;
};
} // namespace nas
......
......@@ -50,7 +50,7 @@ _5GS_Registration_Result::_5GS_Registration_Result(
//------------------------------------------------------------------------------
_5GS_Registration_Result::_5GS_Registration_Result() {
_iei = 0;
length = k5gsRegistrationResultLength;
length = 0;
emergency_registered = false;
NSSAA_performed = false;
SMS_allowed = false;
......@@ -79,13 +79,30 @@ void _5GS_Registration_Result::set(
_value = value;
}
//------------------------------------------------------------------------------
void _5GS_Registration_Result::set(
bool emergency, bool nssaa, bool sms, uint8_t value) {
_iei = 0;
length = k5gsRegistrationResultLength - 1; // without IEI
emergency_registered = emergency;
NSSAA_performed = nssaa;
SMS_allowed = sms;
_value = value;
}
//------------------------------------------------------------------------------
int _5GS_Registration_Result::encode2Buffer(uint8_t* buf, int len) {
Logger::nas_mm().debug("Encoding _5GS_Registration_Result");
if (len < k5gsRegistrationResultLength) {
uint8_t ie_len = 0;
if (_iei) {
ie_len = k5gsRegistrationResultLength;
} else {
ie_len = k5gsRegistrationResultLength - 1;
}
if (len < ie_len) {
Logger::nas_mm().error(
"Buffer length is less than the length of this IE (%d octet)",
k5gsRegistrationResultLength);
"Buffer length is less than the length of this IE (%d octet)", ie_len);
return KEncodeDecodeError;
}
......
......@@ -41,6 +41,7 @@ class _5GS_Registration_Result {
uint8_t getValue();
void set(
const uint8_t iei, bool emergency, bool nssaa, bool sms, uint8_t value);
void set(bool emergency, bool nssaa, bool sms, uint8_t value);
private:
uint8_t _iei;
......
......@@ -37,8 +37,8 @@ using namespace nas;
//------------------------------------------------------------------------------
RegistrationAccept::RegistrationAccept()
: NasMmPlainHeader(EPD_5GS_MM_MSG, REGISTRATION_ACCEPT) {
ie_5g_guti = nullptr;
ie_equivalent_plmns = nullptr;
ie_5g_guti = std::nullopt;
ie_equivalent_plmns = std::nullopt;
ie_allowed_nssai = nullptr;
ie_rejected_nssai = nullptr;
ie_configured_nssai = nullptr;
......@@ -75,44 +75,51 @@ void RegistrationAccept::setHeader(uint8_t security_header_type) {
}
//------------------------------------------------------------------------------
void RegistrationAccept::set_5GS_Registration_Result(
bool emergency, bool nssaa, bool sms, uint8_t value) {
ie_5gs_registration_result.set(0x00, emergency, nssaa, sms, value);
void RegistrationAccept::set5GSRegistrationResult(
bool emergency, bool nssaa, bool sms, const uint8_t& value) {
ie_5gs_registration_result.set(emergency, nssaa, sms, value);
}
//------------------------------------------------------------------------------
void RegistrationAccept::setSUCI_SUPI_format_IMSI(
const string mcc, const string mnc, const string routingInd,
uint8_t protection_sch_id, const string msin) {
const std::string& mcc, const std::string& mnc,
const std::string& routingInd, const uint8_t& protection_sch_id,
const std::string& msin) {
if (protection_sch_id != NULL_SCHEME) {
Logger::nas_mm().error(
"Encoding SUCI and SUPI format for IMSI error, please choose right "
"interface");
"scheme");
return;
} else {
ie_5g_guti = new _5GSMobileIdentity();
ie_5g_guti->setSuciWithSupiImsi(
_5GSMobileIdentity ie_5g_guti_tmp = {};
ie_5g_guti_tmp.setIEI(kIei5gGuti);
ie_5g_guti_tmp.setSuciWithSupiImsi(
mcc, mnc, routingInd, protection_sch_id, msin);
ie_5g_guti->setIEI(0x77);
ie_5g_guti = std::optional<_5GSMobileIdentity>(ie_5g_guti_tmp);
}
}
//------------------------------------------------------------------------------
void RegistrationAccept::setSUCI_SUPI_format_IMSI(
const string mcc, const string mnc, const string routingInd,
uint8_t protection_sch_id, uint8_t hnpki, const string msin) {}
const std::string& mcc, const std::string& mnc,
const std::string& routingInd, const uint8_t& protection_sch_id,
const uint8_t& hnpki, const std::string& msin) {
// TODO:
}
//------------------------------------------------------------------------------
void RegistrationAccept::set5G_GUTI(
const string mcc, const string mnc, const string amfRegionId,
const string amfSetId, const string amfPointer, const uint32_t tmsi) {
ie_5g_guti = new _5GSMobileIdentity();
int regionId = fromString<int>(amfRegionId);
int setId = fromString<int>(amfSetId);
int pointer = fromString<int>(amfPointer);
ie_5g_guti->set5GGUTI(
const std::string& mcc, const std::string& mnc,
const std::string& amfRegionId, const std::string& amfSetId,
const std::string& amfPointer, const uint32_t& tmsi) {
_5GSMobileIdentity ie_5g_guti_tmp = {};
int regionId = fromString<int>(amfRegionId);
int setId = fromString<int>(amfSetId);
int pointer = fromString<int>(amfPointer);
ie_5g_guti_tmp.setIEI(kIei5gGuti);
ie_5g_guti_tmp.set5GGUTI(
mcc, mnc, (uint8_t) regionId, (uint16_t) setId, (uint8_t) pointer, tmsi);
ie_5g_guti->setIEI(0x77);
ie_5g_guti = std::optional<_5GSMobileIdentity>(ie_5g_guti_tmp);
}
//------------------------------------------------------------------------------
......@@ -123,8 +130,10 @@ void RegistrationAccept::set5G_S_TMSI() {}
//------------------------------------------------------------------------------
void RegistrationAccept::setEquivalent_PLMNs(
uint8_t MNC_MCC1, uint8_t MNC_MCC2, uint8_t MNC_MCC3) {
ie_equivalent_plmns = new PLMN_List(0x4A, MNC_MCC1, MNC_MCC2, MNC_MCC3);
const std::vector<nas_plmn_t>& list) {
PLMN_List ie_equivalent_plmns_tmp = {};
ie_equivalent_plmns_tmp.set(kEquivalentPlmns, list);
ie_equivalent_plmns = std::optional<PLMN_List>(ie_equivalent_plmns_tmp);
}
//------------------------------------------------------------------------------
......@@ -285,11 +294,11 @@ int RegistrationAccept::encode2Buffer(uint8_t* buf, int len) {
return 0;
}
if (!ie_5g_guti) {
if (!ie_5g_guti.has_value()) {
Logger::nas_mm().warn("IE ie_5g_guti is not available");
} else {
int size =
ie_5g_guti->encode2Buffer(buf + encoded_size, len - encoded_size);
int size = ie_5g_guti.value().encode2Buffer(
buf + encoded_size, len - encoded_size);
if (size) {
encoded_size += size;
} else {
......@@ -309,10 +318,10 @@ int RegistrationAccept::encode2Buffer(uint8_t* buf, int len) {
return 0;
}
}
if (!ie_equivalent_plmns) {
if (!ie_equivalent_plmns.has_value()) {
Logger::nas_mm().warn("IE ie_equivalent_plmns is not available");
} else {
if (int size = ie_equivalent_plmns->encode2Buffer(
if (int size = ie_equivalent_plmns.value().encode2Buffer(
buf + encoded_size, len - encoded_size)) {
encoded_size += size;
} else {
......@@ -609,8 +618,7 @@ int RegistrationAccept::encode2Buffer(uint8_t* buf, int len) {
}
//------------------------------------------------------------------------------
int RegistrationAccept::decodeFromBuffer(
NasMmPlainHeader* header, uint8_t* buf, int len) {
int RegistrationAccept::decodeFromBuffer(uint8_t* buf, int len) {
Logger::nas_mm().debug("Decoding RegistrationAccept message");
int decoded_size = 3;
......@@ -657,10 +665,11 @@ int RegistrationAccept::decodeFromBuffer(
switch (octet) {
case 0x77: {
Logger::nas_mm().debug("Decoding IEI (0x77)");
ie_5g_guti = new _5GSMobileIdentity();
decoded_size += ie_5g_guti->decodeFromBuffer(
_5GSMobileIdentity ie_5g_guti_tmp = {};
decoded_size += ie_5g_guti_tmp.decodeFromBuffer(
buf + decoded_size, len - decoded_size, true);
octet = *(buf + decoded_size);
ie_5g_guti = std::optional<_5GSMobileIdentity>(ie_5g_guti_tmp);
octet = *(buf + decoded_size);
Logger::nas_mm().debug("Next IEI (0x%x)", octet);
} break;
case 0x15: {
......@@ -829,10 +838,11 @@ int RegistrationAccept::decodeFromBuffer(
} break;
case 0x4A: {
Logger::nas_mm().debug("Decoding IEI (0x4A)");
ie_equivalent_plmns = new PLMN_List();
decoded_size += ie_equivalent_plmns->decodeFromBuffer(
PLMN_List ie_equivalent_plmns_tmp = {};
decoded_size += ie_equivalent_plmns_tmp.decodeFromBuffer(
buf + decoded_size, len - decoded_size, true);
octet = *(buf + decoded_size);
ie_equivalent_plmns = std::optional<PLMN_List>(ie_equivalent_plmns_tmp);
octet = *(buf + decoded_size);
Logger::nas_mm().debug("Next IEI (0x%x)", octet);
} break;
}
......
......@@ -36,29 +36,31 @@ class RegistrationAccept : public NasMmPlainHeader {
bool verifyHeader(); // TODO
int encode2Buffer(uint8_t* buf, int len);
int decodeFromBuffer(NasMmPlainHeader* header, uint8_t* buf, int len);
int decodeFromBuffer(uint8_t* buf, int len);
void set_5GS_Registration_Result(
bool emergency, bool nssaa, bool sms, uint8_t value);
void set5GSRegistrationResult(
bool emergency, bool nssaa, bool sms, const uint8_t& value);
// TODO: Get
// 5GSMobileIdentity
void setSUCI_SUPI_format_IMSI(
const string mcc, const string mnc, const string routingInd,
uint8_t protection_sch_id, const string msin);
const std::string& mcc, const std::string& mnc,
const std::string& routingInd, const uint8_t& protection_sch_id,
const std::string& msin);
void setSUCI_SUPI_format_IMSI(
const string mcc, const string mnc, const string routingInd,
uint8_t protection_sch_id, uint8_t hnpki, const string msin);
const std::string& mcc, const std::string& mnc,
const std::string& routingInd, const uint8_t& protection_sch_id,
const uint8_t& hnpki, const std::string& msin);
void set5G_GUTI(
const string mcc, const string mnc, const string amfRegionId,
const string amfSetId, const string amfPointer, const uint32_t tmsi);
void setIMEI_IMEISV();
void set5G_S_TMSI();
const std::string& mcc, const std::string& mnc,
const std::string& amfRegionId, const std::string& amfSetId,
const std::string& amfPointer, const uint32_t& tmsi);
void setIMEI_IMEISV(); // TODO:
void set5G_S_TMSI(); // TODO:
// TODO: Get
// Equivalent PLMNs
void setEquivalent_PLMNs(
uint8_t MNC_MCC1, uint8_t MNC_MCC2, uint8_t MNC_MCC3);
void setEquivalent_PLMNs(const std::vector<nas_plmn_t>& list);
// TODO: Get
void setTaiList(std::vector<p_tai_t> tai_list);
......@@ -149,8 +151,8 @@ class RegistrationAccept : public NasMmPlainHeader {
public:
_5GS_Registration_Result ie_5gs_registration_result; // Mandatory
_5GSMobileIdentity* ie_5g_guti; // Optional
PLMN_List* ie_equivalent_plmns; // Optional
std::optional<_5GSMobileIdentity> ie_5g_guti; // Optional
std::optional<PLMN_List> ie_equivalent_plmns; // Optional
_5GSTrackingAreaIdList* ie_tai_list; // Optional
NSSAI* ie_allowed_nssai; // Optional
Rejected_NSSAI* ie_rejected_nssai; // Optional
......
......@@ -62,10 +62,11 @@ int NasUtils::encodeMccMnc2Buffer(
//------------------------------------------------------------------------------
int NasUtils::decodeMccMncFromBuffer(
std::string& mcc_str, std::string& mnc_str, uint8_t* buf, int len) {
if (len < 3) {
if (len < kMccMncLength) {
Logger::nas_mm().error(
"Buffer length is less than the minimum length of this IE (3 octet)");
return -1;
"Buffer length is less than the minimum length of this IE (%d octet)",
kMccMncLength);
return KEncodeDecodeError;
}
int decoded_size = 0;
uint8_t octet = 0;
......
......@@ -24,6 +24,7 @@
#include <iostream>
#include <string>
constexpr uint8_t kMccMncLength = 3;
class NasUtils {
public:
......
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