Commit f61ad481 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Define IEs for supporting Static UE IP addr

parent 58fce642
......@@ -318,6 +318,18 @@ typedef struct pdu_session_type_s {
pdu_session_type_s(const uint8_t& p) : pdu_session_type(p) {}
pdu_session_type_s(const struct pdu_session_type_s& p)
: pdu_session_type(p.pdu_session_type) {}
pdu_session_type_s(const std::string& s) {
if (s.compare("IPV4") == 0) {
pdu_session_type = pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4;
} else if (s.compare("IPV6") == 0) {
pdu_session_type = pdu_session_type_e::PDU_SESSION_TYPE_E_IPV6;
} else if (s.compare("IPV4V6") == 0) {
pdu_session_type = pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4V6;
} else {
pdu_session_type =
pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4; // Default value
}
}
bool operator==(const struct pdu_session_type_s& p) const {
return (p.pdu_session_type == pdu_session_type);
}
......@@ -329,6 +341,7 @@ typedef struct pdu_session_type_s {
const std::string& toString() const {
return pdu_session_type_e2str.at(pdu_session_type);
}
} pdu_session_type_t;
//-------------------------------------
......
......@@ -142,15 +142,6 @@ struct imsi_s {
};
typedef struct imsi_s imsi_t;
//-------------------------------------
// 8.9 IP Address
typedef struct ip_address_s {
bool is_ipv4; // if not ipv4, then it is ipv6
union {
struct in_addr ipv4_address;
struct in6_addr ipv6_address;
} address;
} ip_address_t;
//-------------------------------------
// 8.10 Mobile Equipment Identity (MEI)
// The ME Identity field contains either the IMEI or the IMEISV as defined in
......
......@@ -38,6 +38,18 @@ typedef struct ssc_mode_s {
ssc_mode_s() : ssc_mode(SSC_MODE_1) {}
ssc_mode_s(ssc_mode_e mode) : ssc_mode(mode) {}
ssc_mode_s(const struct ssc_mode_s& p) : ssc_mode(p.ssc_mode) {}
ssc_mode_s(const std::string& s) {
if (s.compare("SSC_MODE_1") == 0) {
ssc_mode = ssc_mode_e::SSC_MODE_1;
} else if (s.compare("SSC_MODE_2") == 0) {
ssc_mode = ssc_mode_e::SSC_MODE_2;
} else if (s.compare("SSC_MODE_3") == 0) {
ssc_mode = ssc_mode_e::SSC_MODE_3;
} else {
ssc_mode = ssc_mode_e::SSC_MODE_1; // default mode
}
}
} ssc_mode_t;
typedef struct pdu_session_types_s {
......@@ -50,12 +62,106 @@ typedef struct ssc_modes_s {
std::vector<ssc_mode_t> allowed_ssc_modes;
} ssc_modes_t;
enum ip_address_type_value_e {
IP_ADDRESS_TYPE_IPV4_ADDRESS = 0,
IP_ADDRESS_TYPE_IPV6_ADDRESS = 1,
IP_ADDRESS_TYPE_IPV6_PREFIX = 2
};
typedef struct ipv6_prefix_s {
struct in6_addr prefix;
uint8_t prefix_len;
std::string to_string() const {
return conv::toString(prefix) + "/" + std::to_string(prefix_len);
}
} ipv6_prefix_t;
typedef struct ip_address_s {
uint8_t ip_address_type;
union {
struct in_addr ipv4_address;
struct in6_addr ipv6_address;
ipv6_prefix_t ipv6_prefix;
} u1;
bool operator==(const struct ip_address_s& i) const {
if ((i.ip_address_type == this->ip_address_type) &&
(i.u1.ipv4_address.s_addr == this->u1.ipv4_address.s_addr) &&
(i.u1.ipv6_address.s6_addr32[0] ==
this->u1.ipv6_address.s6_addr32[0]) &&
(i.u1.ipv6_address.s6_addr32[1] ==
this->u1.ipv6_address.s6_addr32[1]) &&
(i.u1.ipv6_address.s6_addr32[2] ==
this->u1.ipv6_address.s6_addr32[2]) &&
(i.u1.ipv6_address.s6_addr32[3] ==
this->u1.ipv6_address.s6_addr32[3]) &&
(i.u1.ipv6_prefix.prefix_len == this->u1.ipv6_prefix.prefix_len) &&
(i.u1.ipv6_prefix.prefix.s6_addr32[0] ==
this->u1.ipv6_prefix.prefix.s6_addr32[0]) &&
(i.u1.ipv6_prefix.prefix.s6_addr32[1] ==
this->u1.ipv6_prefix.prefix.s6_addr32[1]) &&
(i.u1.ipv6_prefix.prefix.s6_addr32[2] ==
this->u1.ipv6_prefix.prefix.s6_addr32[2]) &&
(i.u1.ipv6_prefix.prefix.s6_addr32[3] ==
this->u1.ipv6_prefix.prefix.s6_addr32[3])) {
return true;
} else {
return false;
}
};
bool operator==(const struct in_addr& a) const {
if ((IP_ADDRESS_TYPE_IPV4_ADDRESS == this->ip_address_type) &&
(a.s_addr == u1.ipv4_address.s_addr)) {
return true;
} else {
return false;
}
};
bool operator==(const struct in6_addr& i) const {
if ((IP_ADDRESS_TYPE_IPV6_ADDRESS == this->ip_address_type) &&
(i.s6_addr32[0] == this->u1.ipv6_address.s6_addr32[0]) &&
(i.s6_addr32[1] == this->u1.ipv6_address.s6_addr32[1]) &&
(i.s6_addr32[2] == this->u1.ipv6_address.s6_addr32[2]) &&
(i.s6_addr32[3] == this->u1.ipv6_address.s6_addr32[3])) {
return true;
} else {
return false;
}
};
bool operator==(const ipv6_prefix_t& i) const {
if ((IP_ADDRESS_TYPE_IPV6_PREFIX == this->ip_address_type) &&
(i.prefix_len == this->u1.ipv6_prefix.prefix_len) &&
(i.prefix.s6_addr32[0] == this->u1.ipv6_prefix.prefix.s6_addr32[0]) &&
(i.prefix.s6_addr32[1] == this->u1.ipv6_prefix.prefix.s6_addr32[1]) &&
(i.prefix.s6_addr32[2] == this->u1.ipv6_prefix.prefix.s6_addr32[2]) &&
(i.prefix.s6_addr32[3] == this->u1.ipv6_prefix.prefix.s6_addr32[3])) {
return true;
} else {
return false;
}
};
std::string to_string() const {
if (IP_ADDRESS_TYPE_IPV4_ADDRESS == this->ip_address_type) {
return conv::toString(u1.ipv4_address);
} else if (IP_ADDRESS_TYPE_IPV6_ADDRESS == this->ip_address_type) {
return conv::toString(u1.ipv6_address);
} else if (IP_ADDRESS_TYPE_IPV6_PREFIX == this->ip_address_type) {
return u1.ipv6_prefix.to_string();
}
return std::string("Unknown IP Address Type");
}
} ip_address_t;
typedef struct dnn_configuration_s {
pdu_session_types_t pdu_session_types;
ssc_modes_t ssc_modes;
session_ambr_t session_ambr;
subscribed_default_qos_t _5g_qos_profile;
// staticIpAddresses
std::vector<ip_address_t> static_ip_addresses;
} dnn_configuration_t;
#endif
......@@ -835,6 +835,9 @@ bool smf_sbi::get_sm_data(
const supi64_t& supi, const std::string& dnn, const snssai_t& snssai,
std::shared_ptr<session_management_subscription> subscription) {
nlohmann::json jsonData = {};
std::string query_str = {};
query_str = "?single-nssai={\"sst\":" + std::to_string(snssai.sST) +
",\"sd\":" + snssai.sD + "}&dnn=oai";
std::string url =
std::string(inet_ntoa(*((struct in_addr*) &smf_cfg.udm_addr.ipv4_addr))) +
":" + std::to_string(smf_cfg.udm_addr.port) + NUDM_SDM_BASE +
......@@ -866,7 +869,9 @@ bool smf_sbi::get_sm_data(
Logger::smf_sbi().debug("Got result for promise ID %d", promise_id);
Logger::smf_sbi().debug("Response data %s", response_data.c_str());
Logger::smf_sbi().debug(
"NF Instance Registration, response from NRF, HTTP Code: %u", httpCode);
"Session Management Subscription Data Retrieval, response from UDM, HTTP "
"Code: %u",
httpCode);
if (static_cast<http_response_codes_e>(httpCode) ==
http_response_codes_e::HTTP_RESPONSE_CODE_OK) {
......@@ -887,72 +892,83 @@ bool smf_sbi::get_sm_data(
// Process the response
if (!jsonData.empty()) {
Logger::smf_sbi().debug("Response from UDM %s", jsonData.dump().c_str());
// Verify SNSSAI
if (jsonData.find("singleNssai") == jsonData.end()) return false;
if (jsonData["singleNssai"].find("sst") != jsonData["singleNssai"].end()) {
std::string sst = jsonData["singleNssai"]["sst"];
if (sst.compare(std::to_string(snssai.sST)) != 0) {
return false;
}
}
if (jsonData["singleNssai"].find("sd") != jsonData["singleNssai"].end()) {
std::string sd = jsonData["singleNssai"]["sd"];
if (sd.compare(snssai.sD) != 0) {
return false;
}
}
// Retrieve SessionManagementSubscription and store in the context
for (nlohmann::json::iterator it = jsonData["dnnConfigurations"].begin();
it != jsonData["dnnConfigurations"].end(); ++it) {
Logger::smf_sbi().debug("DNN %s", it.key().c_str());
if (it.key().compare(dnn) != 0) break;
try {
std::shared_ptr<dnn_configuration_t> dnn_configuration =
std::make_shared<dnn_configuration_t>();
pdu_session_type_t pdu_session_type(
pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4);
// PDU Session Type (Mandatory)
std::string default_session_type =
it.value()["pduSessionTypes"]["defaultSessionType"];
Logger::smf_sbi().debug(
"Default session type %s", default_session_type.c_str());
if (default_session_type.compare("IPV4") == 0) {
pdu_session_type.pdu_session_type =
pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4;
} else if (default_session_type.compare("IPV6") == 0) {
pdu_session_type.pdu_session_type =
pdu_session_type_e::PDU_SESSION_TYPE_E_IPV6;
} else if (default_session_type.compare("IPV4V6") == 0) {
pdu_session_type.pdu_session_type =
pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4V6;
}
pdu_session_type_t pdu_session_type(default_session_type);
dnn_configuration->pdu_session_types.default_session_type =
pdu_session_type;
// SSC_Mode
ssc_mode_t ssc_mode(ssc_mode_e::SSC_MODE_1);
// SSC_Mode (Mandatory)
std::string default_ssc_mode = it.value()["sscModes"]["defaultSscMode"];
Logger::smf_sbi().debug(
"Default SSC Mode %s", default_ssc_mode.c_str());
if (default_ssc_mode.compare("SSC_MODE_1") == 0) {
dnn_configuration->ssc_modes.default_ssc_mode =
ssc_mode_t(ssc_mode_e::SSC_MODE_1);
} else if (default_ssc_mode.compare("SSC_MODE_2") == 0) {
dnn_configuration->ssc_modes.default_ssc_mode =
ssc_mode_t(ssc_mode_e::SSC_MODE_2);
} else if (default_ssc_mode.compare("SSC_MODE_3") == 0) {
dnn_configuration->ssc_modes.default_ssc_mode =
ssc_mode_t(ssc_mode_e::SSC_MODE_3);
ssc_mode_t ssc_mode(default_ssc_mode);
dnn_configuration->ssc_modes.default_ssc_mode = ssc_mode;
// 5gQosProfile (Optional)
if (it.value().find("5gQosProfile") != it.value().end()) {
dnn_configuration->_5g_qos_profile._5qi =
it.value()["5gQosProfile"]["5qi"];
dnn_configuration->_5g_qos_profile.arp.priority_level =
it.value()["5gQosProfile"]["arp"]["priorityLevel"];
dnn_configuration->_5g_qos_profile.arp.preempt_cap =
it.value()["5gQosProfile"]["arp"]["preemptCap"];
dnn_configuration->_5g_qos_profile.arp.preempt_vuln =
it.value()["5gQosProfile"]["arp"]["preemptVuln"];
// Optinal
if (it.value()["5gQosProfile"].find("") !=
it.value()["5gQosProfile"].end()) {
dnn_configuration->_5g_qos_profile.priority_level =
it.value()["5gQosProfile"]["5QiPriorityLevel"];
}
}
// 5gQosProfile
dnn_configuration->_5g_qos_profile._5qi =
it.value()["5gQosProfile"]["5qi"];
dnn_configuration->_5g_qos_profile.arp.priority_level =
it.value()["5gQosProfile"]["arp"]["priorityLevel"];
dnn_configuration->_5g_qos_profile.arp.preempt_cap =
it.value()["5gQosProfile"]["arp"]["preemptCap"];
dnn_configuration->_5g_qos_profile.arp.preempt_vuln =
it.value()["5gQosProfile"]["arp"]["preemptVuln"];
dnn_configuration->_5g_qos_profile.priority_level =
1; // TODO: hardcoded
// session_ambr
dnn_configuration->session_ambr.uplink =
it.value()["sessionAmbr"]["uplink"];
dnn_configuration->session_ambr.downlink =
it.value()["sessionAmbr"]["downlink"];
Logger::smf_sbi().debug(
"Session AMBR Uplink %s, Downlink %s",
dnn_configuration->session_ambr.uplink.c_str(),
dnn_configuration->session_ambr.downlink.c_str());
// session_ambr: Optional
if (it.value().find("sessionAmbr") != it.value().end()) {
dnn_configuration->session_ambr.uplink =
it.value()["sessionAmbr"]["uplink"];
dnn_configuration->session_ambr.downlink =
it.value()["sessionAmbr"]["downlink"];
Logger::smf_sbi().debug(
"Session AMBR Uplink %s, Downlink %s",
dnn_configuration->session_ambr.uplink.c_str(),
dnn_configuration->session_ambr.downlink.c_str());
}
// Optional: Static IP Address
if (it.value().find("staticIpAddress") != it.value().end()) {
for (const auto& ip_addr : it.value()["staticIpAddress"]) {
}
}
subscription->insert_dnn_configuration(it.key(), dnn_configuration);
return true;
} catch (nlohmann::json::exception& e) {
Logger::smf_sbi().warn(
"Exception message %s, exception id %d ", e.what(), e.id);
......
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