Commit ba9e0fb7 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen
Browse files

Merge branch 'n2_handover' into 'develop'

N2 handover

See merge request !62
parents fab3bec1 40751a58
...@@ -55,6 +55,6 @@ Based on document **3GPP TS 23.501 v16.0.0 (Section 6.2.2)**. ...@@ -55,6 +55,6 @@ Based on document **3GPP TS 23.501 v16.0.0 (Section 6.2.2)**.
| 12 | Determine SSC mode of a session​ | :heavy_check_mark: | Only support SSC mode 1​ | | 12 | Determine SSC mode of a session​ | :heavy_check_mark: | Only support SSC mode 1​ |
| 13 | Initiator of AN specific SM information, sent via AMF over N2 to AN | :heavy_check_mark: | | | 13 | Initiator of AN specific SM information, sent via AMF over N2 to AN | :heavy_check_mark: | |
| 14 | Support for Control Plane CIoT 5GS Optimisation | :x: | | | 14 | Support for Control Plane CIoT 5GS Optimisation | :x: | |
| 15 | Support of header compression. ​ | :x: | | | 15 | Support of header compression ​ | :x: | |
| 16 | Act as I-SMF in deployments | :x: | | | 16 | Act as I-SMF in deployments | :x: | |
| 17 | Provisioning of external parameters | :x: | | | 17 | Provisioning of external parameters | :x: | |
...@@ -96,9 +96,12 @@ void IndividualSMContextApi::release_sm_context_handler( ...@@ -96,9 +96,12 @@ void IndividualSMContextApi::release_sm_context_handler(
Logger::smf_api_server().debug("Request body: %s\n", request.body().c_str()); Logger::smf_api_server().debug("Request body: %s\n", request.body().c_str());
SmContextReleaseMessage smContextReleaseMessage = {}; SmContextReleaseMessage smContextReleaseMessage = {};
// simple parser // Simple parser
mime_parser sp = {}; mime_parser sp = {};
sp.parse(request.body()); if (!sp.parse(request.body())) {
response.send(Pistache::Http::Code::Bad_Request);
return;
}
std::vector<mime_part> parts = {}; std::vector<mime_part> parts = {};
sp.get_mime_parts(parts); sp.get_mime_parts(parts);
...@@ -178,9 +181,12 @@ void IndividualSMContextApi::update_sm_context_handler( ...@@ -178,9 +181,12 @@ void IndividualSMContextApi::update_sm_context_handler(
Logger::smf_api_server().debug("Request body: %s\n", request.body().c_str()); Logger::smf_api_server().debug("Request body: %s\n", request.body().c_str());
SmContextUpdateMessage smContextUpdateMessage = {}; SmContextUpdateMessage smContextUpdateMessage = {};
// simple parser // Simple parser
mime_parser sp = {}; mime_parser sp = {};
sp.parse(request.body()); if (!sp.parse(request.body())) {
response.send(Pistache::Http::Code::Bad_Request);
return;
}
std::vector<mime_part> parts = {}; std::vector<mime_part> parts = {};
sp.get_mime_parts(parts); sp.get_mime_parts(parts);
......
...@@ -88,25 +88,28 @@ void SMContextsCollectionApi::post_sm_contexts_handler( ...@@ -88,25 +88,28 @@ void SMContextsCollectionApi::post_sm_contexts_handler(
SmContextMessage smContextMessage = {}; SmContextMessage smContextMessage = {};
SmContextCreateData smContextCreateData = {}; SmContextCreateData smContextCreateData = {};
// simple parser // Simple parser
mime_parser sp = {}; mime_parser sp = {};
sp.parse(request.body()); if (!sp.parse(request.body())) {
response.send(Pistache::Http::Code::Bad_Request);
return;
}
std::vector<mime_part> parts = {}; std::vector<mime_part> parts = {};
sp.get_mime_parts(parts); sp.get_mime_parts(parts);
uint8_t size = parts.size(); uint8_t size = parts.size();
Logger::smf_api_server().debug("Number of MIME parts %d", size); Logger::smf_api_server().debug("Number of MIME parts %d", size);
// at least 2 parts for Json data and N1 (+ N2) // At least 2 parts for Json data and N1 (+ N2)
if (size < 2) { if (size < 2) {
response.send(Pistache::Http::Code::Bad_Request); response.send(Pistache::Http::Code::Bad_Request);
return; return;
} }
// step 2. process the request // Step 2. process the request
try { try {
nlohmann::json::parse(parts[0].body.c_str()).get_to(smContextCreateData); nlohmann::json::parse(parts[0].body.c_str()).get_to(smContextCreateData);
smContextMessage.setJsonData(smContextCreateData); smContextMessage.setJsonData(smContextCreateData);
// must include N1 NAS msg // Must include N1 NAS msg
if (parts[1].content_type.compare("application/vnd.3gpp.5gnas") == 0) { if (parts[1].content_type.compare("application/vnd.3gpp.5gnas") == 0) {
smContextMessage.setBinaryDataN1SmMessage(parts[1].body); smContextMessage.setBinaryDataN1SmMessage(parts[1].body);
} else { } else {
......
...@@ -53,7 +53,7 @@ void SubscriptionsCollectionApi::create_individual_subcription_handler( ...@@ -53,7 +53,7 @@ void SubscriptionsCollectionApi::create_individual_subcription_handler(
Pistache::Http::ResponseWriter response) { Pistache::Http::ResponseWriter response) {
// Getting the body param // Getting the body param
NsmfEventExposure nsmfEventExposure; NsmfEventExposure nsmfEventExposure = {};
try { try {
nlohmann::json::parse(request.body()).get_to(nsmfEventExposure); nlohmann::json::parse(request.body()).get_to(nsmfEventExposure);
......
...@@ -17,7 +17,21 @@ namespace oai { ...@@ -17,7 +17,21 @@ namespace oai {
namespace smf_server { namespace smf_server {
namespace model { namespace model {
GlobalRanNodeId::GlobalRanNodeId() {} GlobalRanNodeId::GlobalRanNodeId() {
m_N3IwfId = "";
m_N3IwfIdIsSet = false;
m_GNbIdIsSet = false;
m_NgeNbId = "";
m_NgeNbIdIsSet = false;
m_WagfId = "";
m_WagfIdIsSet = false;
m_TngfId = "";
m_TngfIdIsSet = false;
m_Nid = "";
m_NidIsSet = false;
m_ENbId = "";
m_ENbIdIsSet = false;
}
GlobalRanNodeId::~GlobalRanNodeId() {} GlobalRanNodeId::~GlobalRanNodeId() {}
...@@ -26,10 +40,146 @@ void GlobalRanNodeId::validate() { ...@@ -26,10 +40,146 @@ void GlobalRanNodeId::validate() {
} }
void to_json(nlohmann::json& j, const GlobalRanNodeId& o) { void to_json(nlohmann::json& j, const GlobalRanNodeId& o) {
j = nlohmann::json(); j = nlohmann::json();
j["plmnId"] = o.m_PlmnId;
if (o.n3IwfIdIsSet()) j["n3IwfId"] = o.m_N3IwfId;
if (o.gNbIdIsSet()) j["gNbId"] = o.m_GNbId;
if (o.ngeNbIdIsSet()) j["ngeNbId"] = o.m_NgeNbId;
if (o.wagfIdIsSet()) j["wagfId"] = o.m_WagfId;
if (o.tngfIdIsSet()) j["tngfId"] = o.m_TngfId;
if (o.nidIsSet()) j["nid"] = o.m_Nid;
if (o.eNbIdIsSet()) j["eNbId"] = o.m_ENbId;
}
void from_json(const nlohmann::json& j, GlobalRanNodeId& o) {
j.at("plmnId").get_to(o.m_PlmnId);
if (j.find("n3IwfId") != j.end()) {
j.at("n3IwfId").get_to(o.m_N3IwfId);
o.m_N3IwfIdIsSet = true;
}
if (j.find("gNbId") != j.end()) {
j.at("gNbId").get_to(o.m_GNbId);
o.m_GNbIdIsSet = true;
}
if (j.find("ngeNbId") != j.end()) {
j.at("ngeNbId").get_to(o.m_NgeNbId);
o.m_NgeNbIdIsSet = true;
}
if (j.find("wagfId") != j.end()) {
j.at("wagfId").get_to(o.m_WagfId);
o.m_WagfIdIsSet = true;
}
if (j.find("tngfId") != j.end()) {
j.at("tngfId").get_to(o.m_TngfId);
o.m_TngfIdIsSet = true;
}
if (j.find("nid") != j.end()) {
j.at("nid").get_to(o.m_Nid);
o.m_NidIsSet = true;
}
if (j.find("eNbId") != j.end()) {
j.at("eNbId").get_to(o.m_ENbId);
o.m_ENbIdIsSet = true;
}
} }
void from_json(const nlohmann::json& j, GlobalRanNodeId& o) {} PlmnId GlobalRanNodeId::getPlmnId() const {
return m_PlmnId;
}
void GlobalRanNodeId::setPlmnId(PlmnId const& value) {
m_PlmnId = value;
}
std::string GlobalRanNodeId::getN3IwfId() const {
return m_N3IwfId;
}
void GlobalRanNodeId::setN3IwfId(std::string const& value) {
m_N3IwfId = value;
m_N3IwfIdIsSet = true;
}
bool GlobalRanNodeId::n3IwfIdIsSet() const {
return m_N3IwfIdIsSet;
}
void GlobalRanNodeId::unsetN3IwfId() {
m_N3IwfIdIsSet = false;
}
GNbId GlobalRanNodeId::getGNbId() const {
return m_GNbId;
}
void GlobalRanNodeId::setGNbId(GNbId const& value) {
m_GNbId = value;
m_GNbIdIsSet = true;
}
bool GlobalRanNodeId::gNbIdIsSet() const {
return m_GNbIdIsSet;
}
void GlobalRanNodeId::unsetGNbId() {
m_GNbIdIsSet = false;
}
std::string GlobalRanNodeId::getNgeNbId() const {
return m_NgeNbId;
}
void GlobalRanNodeId::setNgeNbId(std::string const& value) {
m_NgeNbId = value;
m_NgeNbIdIsSet = true;
}
bool GlobalRanNodeId::ngeNbIdIsSet() const {
return m_NgeNbIdIsSet;
}
void GlobalRanNodeId::unsetNgeNbId() {
m_NgeNbIdIsSet = false;
}
std::string GlobalRanNodeId::getWagfId() const {
return m_WagfId;
}
void GlobalRanNodeId::setWagfId(std::string const& value) {
m_WagfId = value;
m_WagfIdIsSet = true;
}
bool GlobalRanNodeId::wagfIdIsSet() const {
return m_WagfIdIsSet;
}
void GlobalRanNodeId::unsetWagfId() {
m_WagfIdIsSet = false;
}
std::string GlobalRanNodeId::getTngfId() const {
return m_TngfId;
}
void GlobalRanNodeId::setTngfId(std::string const& value) {
m_TngfId = value;
m_TngfIdIsSet = true;
}
bool GlobalRanNodeId::tngfIdIsSet() const {
return m_TngfIdIsSet;
}
void GlobalRanNodeId::unsetTngfId() {
m_TngfIdIsSet = false;
}
std::string GlobalRanNodeId::getNid() const {
return m_Nid;
}
void GlobalRanNodeId::setNid(std::string const& value) {
m_Nid = value;
m_NidIsSet = true;
}
bool GlobalRanNodeId::nidIsSet() const {
return m_NidIsSet;
}
void GlobalRanNodeId::unsetNid() {
m_NidIsSet = false;
}
std::string GlobalRanNodeId::getENbId() const {
return m_ENbId;
}
void GlobalRanNodeId::setENbId(std::string const& value) {
m_ENbId = value;
m_ENbIdIsSet = true;
}
bool GlobalRanNodeId::eNbIdIsSet() const {
return m_ENbIdIsSet;
}
void GlobalRanNodeId::unsetENbId() {
m_ENbIdIsSet = false;
}
} // namespace model } // namespace model
} // namespace smf_server } // namespace smf_server
......
...@@ -19,6 +19,9 @@ ...@@ -19,6 +19,9 @@
#ifndef GlobalRanNodeId_H_ #ifndef GlobalRanNodeId_H_
#define GlobalRanNodeId_H_ #define GlobalRanNodeId_H_
#include <string>
#include "GNbId.h"
#include "PlmnId.h"
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
namespace oai { namespace oai {
...@@ -38,10 +41,81 @@ class GlobalRanNodeId { ...@@ -38,10 +41,81 @@ class GlobalRanNodeId {
///////////////////////////////////////////// /////////////////////////////////////////////
/// GlobalRanNodeId members /// GlobalRanNodeId members
/// <summary>
///
/// </summary>
PlmnId getPlmnId() const;
void setPlmnId(PlmnId const& value);
/// <summary>
///
/// </summary>
std::string getN3IwfId() const;
void setN3IwfId(std::string const& value);
bool n3IwfIdIsSet() const;
void unsetN3IwfId();
/// <summary>
///
/// </summary>
GNbId getGNbId() const;
void setGNbId(GNbId const& value);
bool gNbIdIsSet() const;
void unsetGNbId();
/// <summary>
///
/// </summary>
std::string getNgeNbId() const;
void setNgeNbId(std::string const& value);
bool ngeNbIdIsSet() const;
void unsetNgeNbId();
/// <summary>
///
/// </summary>
std::string getWagfId() const;
void setWagfId(std::string const& value);
bool wagfIdIsSet() const;
void unsetWagfId();
/// <summary>
///
/// </summary>
std::string getTngfId() const;
void setTngfId(std::string const& value);
bool tngfIdIsSet() const;
void unsetTngfId();
/// <summary>
///
/// </summary>
std::string getNid() const;
void setNid(std::string const& value);
bool nidIsSet() const;
void unsetNid();
/// <summary>
///
/// </summary>
std::string getENbId() const;
void setENbId(std::string const& value);
bool eNbIdIsSet() const;
void unsetENbId();
friend void to_json(nlohmann::json& j, const GlobalRanNodeId& o); friend void to_json(nlohmann::json& j, const GlobalRanNodeId& o);
friend void from_json(const nlohmann::json& j, GlobalRanNodeId& o); friend void from_json(const nlohmann::json& j, GlobalRanNodeId& o);
protected: protected:
PlmnId m_PlmnId;
std::string m_N3IwfId;
bool m_N3IwfIdIsSet;
GNbId m_GNbId;
bool m_GNbIdIsSet;
std::string m_NgeNbId;
bool m_NgeNbIdIsSet;
std::string m_WagfId;
bool m_WagfIdIsSet;
std::string m_TngfId;
bool m_TngfIdIsSet;
std::string m_Nid;
bool m_NidIsSet;
std::string m_ENbId;
bool m_ENbIdIsSet;
}; };
} // namespace model } // namespace model
......
...@@ -27,9 +27,12 @@ void HoState::validate() { ...@@ -27,9 +27,12 @@ void HoState::validate() {
void to_json(nlohmann::json& j, const HoState& o) { void to_json(nlohmann::json& j, const HoState& o) {
j = nlohmann::json(); j = nlohmann::json();
j = o.state;
} }
void from_json(const nlohmann::json& j, HoState& o) {} void from_json(const nlohmann::json& j, HoState& o) {
o.state = j.get<std::string>();
}
} // namespace model } // namespace model
} // namespace smf_server } // namespace smf_server
......
...@@ -37,6 +37,7 @@ class HoState { ...@@ -37,6 +37,7 @@ class HoState {
///////////////////////////////////////////// /////////////////////////////////////////////
/// HoState members /// HoState members
std::string state;
friend void to_json(nlohmann::json& j, const HoState& o); friend void to_json(nlohmann::json& j, const HoState& o);
friend void from_json(const nlohmann::json& j, HoState& o); friend void from_json(const nlohmann::json& j, HoState& o);
......
...@@ -85,7 +85,13 @@ void smf_http2_server::start() { ...@@ -85,7 +85,13 @@ void smf_http2_server::start() {
// simple parser // simple parser
mime_parser sp = {}; mime_parser sp = {};
sp.parse(msg); if (!sp.parse(msg)) {
// send reply!!!
response.write_head(
http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
response.end();
return;
}
std::vector<mime_part> parts = {}; std::vector<mime_part> parts = {};
sp.get_mime_parts(parts); sp.get_mime_parts(parts);
...@@ -176,7 +182,13 @@ void smf_http2_server::start() { ...@@ -176,7 +182,13 @@ void smf_http2_server::start() {
// simple parser // simple parser
mime_parser sp = {}; mime_parser sp = {};
sp.parse(msg); if (!sp.parse(msg)) {
// send reply!!!
response.write_head(
http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
response.end();
return;
}
std::vector<mime_part> parts = {}; std::vector<mime_part> parts = {};
sp.get_mime_parts(parts); sp.get_mime_parts(parts);
...@@ -235,7 +247,13 @@ void smf_http2_server::start() { ...@@ -235,7 +247,13 @@ void smf_http2_server::start() {
// simple parser // simple parser
mime_parser sp = {}; mime_parser sp = {};
sp.parse(msg); if (!sp.parse(msg)) {
// send reply!!!
response.write_head(
http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
response.end();
return;
}
std::vector<mime_part> parts = {}; std::vector<mime_part> parts = {};
sp.get_mime_parts(parts); sp.get_mime_parts(parts);
......
...@@ -148,4 +148,15 @@ static const std::vector<std::string> upCnx_state_e2str = { ...@@ -148,4 +148,15 @@ static const std::vector<std::string> upCnx_state_e2str = {
"UPCNX_STATE_ACTIVATED", "UPCNX_STATE_DEACTIVATED", "UPCNX_STATE_ACTIVATED", "UPCNX_STATE_DEACTIVATED",
"UPCNX_STATE_ACTIVATING"}; "UPCNX_STATE_ACTIVATING"};
enum class ho_state_e {
HO_STATE_NONE = 0,
HO_STATE_PREPARING = 1,
HO_STATE_PREPARED = 2,
HO_STATE_COMPLETED = 3,
HO_STATE_CANCELLED = 4
};
static const std::vector<std::string> ho_state_e2str = {
"NONE", "PREPARING", "PREPARED", "COMPLETED", "CANCELLED"};
#endif #endif
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef FILE_3GPP_29_518_SMF_SEEN
#define FILE_3GPP_29_518_SMF_SEEN
#include "3gpp_29.571.h"
#include "3gpp_23.003.h"
typedef struct ng_ran_target_id_s {
global_ran_node_id_t global_ran_node_id;
tai_t tai;
} ng_ran_target_id_t;
#endif
...@@ -51,4 +51,16 @@ enum reflective_qos_attribute_e { RQOS = 1, NO_RQOS = 2 }; ...@@ -51,4 +51,16 @@ enum reflective_qos_attribute_e { RQOS = 1, NO_RQOS = 2 };
static const std::vector<std::string> reflective_qos_attribute_e2str = { static const std::vector<std::string> reflective_qos_attribute_e2str = {
"ERROR", "RQOS", "NO_RQOS"}; "ERROR", "RQOS", "NO_RQOS"};
typedef struct gNB_id_s {
uint8_t bit_length;
std::string gNB_value;
} gNB_id_t; // 22bits to 32bits
typedef struct global_ran_node_id_s {
plmn_t plmn_id;
// n3IwfId:
gNB_id_t gNbId;
// ngeNbId:
} global_ran_node_id_t;
#endif #endif
...@@ -182,35 +182,6 @@ class itti_n11_update_sm_context_response : public itti_n11_msg { ...@@ -182,35 +182,6 @@ class itti_n11_update_sm_context_response : public itti_n11_msg {
session_management_procedures_type_e session_procedure_type; session_management_procedures_type_e session_procedure_type;
}; };
//-----------------------------------------------------------------------------
class itti_n11_update_pdu_session_status : public itti_n11_msg {
public:
itti_n11_update_pdu_session_status(const task_id_t orig, const task_id_t dest)
: itti_n11_msg(N11_SESSION_UPDATE_PDU_SESSION_STATUS, orig, dest),
scid(0),
pdu_session_status(pdu_session_status_e::PDU_SESSION_INACTIVE) {}
itti_n11_update_pdu_session_status(
const itti_n11_update_pdu_session_status& i)
: itti_n11_msg(i),
scid(i.scid),
pdu_session_status(i.pdu_session_status) {}
itti_n11_update_pdu_session_status(
const itti_n11_update_pdu_session_status& i, const task_id_t orig,
const task_id_t dest)
: itti_n11_msg(i, orig, dest),
scid(i.scid),
pdu_session_status(i.pdu_session_status) {}
const char* get_msg_name() {
return "N11_SESSION_UPDATE_PDU_SESSION_STATUS";
};
void set_scid(scid_t id) { scid = id; };
scid_t scid; // SM Context ID
pdu_session_status_e pdu_session_status;
void set_pdu_session_status(pdu_session_status_e status) {
pdu_session_status = status;
};
};