Commit 251022eb authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

finalize PDU Session Modification procedure (step 2 and 3)

parent 0d1c5fd6
......@@ -1586,17 +1586,8 @@ void smf_context::handle_pdu_session_update_sm_context_request(
T3591_TIMER_VALUE_SEC, 0, TASK_SMF_APP, TASK_SMF_APP_TRIGGER_T3591,
sm_context_req_msg.get_pdu_session_id());
sm_context_resp_pending->session_procedure_type = procedure_type;
//don't need to create a procedure to update UPF
//Send ITTI to N11 to send PDUSession_UpdateSMContext Response to AMF
Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name());
int ret = itti_inst->send_msg(sm_context_resp_pending);
if (RETURNok != ret) {
Logger::smf_app().error(
"Could not send ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name());
}
free_wrapper((void**) &qos_rules_ie);
free_wrapper((void**) &qos_flow_description);
......@@ -1607,20 +1598,11 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//PDU Session Modification Command Complete
case PDU_SESSION_MODIFICATION_COMPLETE: {
//PDU Session Modification procedure (Section 4.3.3.2@3GPP TS 23.502)
//TODO: should be verified since mentioned PDU_SESSION_MODIFICATION_COMMAND ACK in spec (see Step 11, section 4.3.3.2@3GPP TS 23.502)
Logger::smf_app().debug("PDU_SESSION_MODIFICATION_COMPLETE");
procedure_type =
session_management_procedures_type_e::PDU_SESSION_MODIFICATION_UE_INITIATED_STEP3;
/* ExtendedProtocolDiscriminator extendedprotocoldiscriminator;
PDUSessionIdentity pdusessionidentity;
ProcedureTransactionIdentity proceduretransactionidentity;
MessageType messagetype;
uint8_t presence;
ExtendedProtocolConfigurationOptions extendedprotocolconfigurationoptions;
*/
/* see section 6.3.2.3@3GPP TS 24.501 V16.1.0
Upon receipt of a PDU SESSION MODIFICATION COMPLETE message, the SMF shall stop timer T3591 and shall
consider the PDU session as modified. If the selected SSC mode of the PDU session is "SSC mode 3" and the PDU
......@@ -1635,18 +1617,8 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//stop T3591
itti_inst->timer_remove(sp.get()->timer_T3591);
//don't need to create a procedure to update UPF
//Send ITTI to N11 to send PDUSession_UpdateSMContext Response to AMF
//No need to create N1/N2 Container
sm_context_resp_pending->session_procedure_type = procedure_type;
Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name());
int ret = itti_inst->send_msg(sm_context_resp_pending);
if (RETURNok != ret) {
Logger::smf_app().error(
"Could not send ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name());
}
//don't need to create a procedure to update UPF
}
break;
......@@ -1684,7 +1656,8 @@ void smf_context::handle_pdu_session_update_sm_context_request(
sp.get()->set_pdu_session_status(
pdu_session_status_e::PDU_SESSION_INACTIVE);
//TODO: Release locally the existing PDU Session (see section 6.3.2.5@3GPP TS 24.501)
} else if (sp.get()->get_pdu_session_status() == pdu_session_status_e::PDU_SESSION_MODIFICATION_PENDING){
} else if (sp.get()->get_pdu_session_status()
== pdu_session_status_e::PDU_SESSION_MODIFICATION_PENDING) {
//Update PDU Session status -> ACTIVE
sp.get()->set_pdu_session_status(
pdu_session_status_e::PDU_SESSION_ACTIVE);
......@@ -1693,19 +1666,8 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//stop T3591
itti_inst->timer_remove(sp.get()->timer_T3591);
//don't need to create a procedure to update UPF
//Send ITTI to N11 to send PDUSession_UpdateSMContext Response to AMF
//No need to create N1/N2 Container
sm_context_resp_pending->session_procedure_type = procedure_type;
Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name());
int ret = itti_inst->send_msg(sm_context_resp_pending);
if (RETURNok != ret) {
Logger::smf_app().error(
"Could not send ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name());
}
//don't need to create a procedure to update UPF
}
break;
......@@ -1858,23 +1820,12 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//Stop timer T3592
itti_inst->timer_remove(sp.get()->timer_T3592);
//don't need to create a procedure to update UPF
//Send ITTI to N11 to send PDUSession_UpdateSMContext Response to AMF
//No need to create N1/N2 Container
sm_context_resp_pending->session_procedure_type = procedure_type;
Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name());
int ret = itti_inst->send_msg(sm_context_resp_pending);
if (RETURNok != ret) {
Logger::smf_app().error(
"Could not send ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name());
}
//don't need to create a procedure to update UPF
//TODO: SMF invokes Nsmf_PDUSession_SMContextStatusNotify to notify AMF that the SM context for this PDU Session is released
//TODO: if dynamic PCC applied, SMF invokes an SM Policy Association Termination
//TODO: SMF unsubscribes from Session Management Subscription data changes notification from UDM by invoking Numd_SDM_Unsubscribe
if (sd.get()->get_number_pdu_sessions() == 0) {
Logger::smf_app().debug(
"Unsubscribe from Session Management Subscription data changes notification from UDM");
......@@ -2007,6 +1958,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
(decoded_msg->dLQosFlowPerTNLInformation.associatedQosFlowList
.list.array[i])->qosFlowIdentifier);
}
//need to update UPF accordingly
update_upf = true;
}
......@@ -2016,7 +1968,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
case n2_sm_info_type_e::PDU_RES_MOD_RSP: {
Logger::smf_app().info("PDU_RES_MOD_RSP");
Logger::smf_app().info(
"PDU Session Modification, processing N2 SM Information");
"PDU Session Modification Procedure, processing N2 SM Information");
procedure_type =
session_management_procedures_type_e::PDU_SESSION_MODIFICATION_UE_INITIATED_STEP2;
......@@ -2026,63 +1978,54 @@ void smf_context::handle_pdu_session_update_sm_context_request(
std::make_shared<Ngap_PDUSessionResourceModifyResponseTransfer_t>();
int decode_status = smf_n1_n2_inst.decode_n2_sm_information(
decoded_msg, n2_sm_information);
if (decode_status == RETURNerror) {
Logger::smf_api_server().warn("asn_decode failed");
//send error to AMF
Logger::smf_app().warn(
"Decode N2 SM (Ngap_PDUSessionResourceModifyResponseTransfer) failed!");
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_N2_SM_ERROR]);
smContextUpdateError.setError(problem_details);
//TODO: need to verify with/without N1 SM
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
//24.501: response with a 5GSM STATUS message including cause "#95 Semantically incorrect message"
smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_95_SEMANTICALLY_INCORRECT_MESSAGE);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden, n1_sm_msg_hex);
Pistache::Http::Code::Forbidden);
return;
}
/*
struct Ngap_UPTransportLayerInformation *dL_NGU_UP_TNLInformation;
struct Ngap_UPTransportLayerInformation *uL_NGU_UP_TNLInformation;
struct Ngap_QosFlowAddOrModifyResponseList *qosFlowAddOrModifyResponseList;
struct Ngap_QosFlowPerTNLInformationList *additionalDLQosFlowPerTNLInformation;
struct Ngap_QosFlowListWithCause *qosFlowFailedToAddOrModifyList;
struct Ngap_ProtocolExtensionContainer *iE_Extensions;
*/
//see section 8.2.3 (PDU Session Resource Modify) @3GPP TS 38.413
//if dL_NGU_UP_TNLInformation is included, it shall be considered as the new DL transport layer addr for the PDU session (should be verified)
//TODO: may include uL_NGU_UP_TNLInformation (mapping between each new DL transport layer address and the corresponding UL transport layer address)
fteid_t dl_teid;
memcpy(
&dl_teid.ipv4_address,
&dl_teid.teid_gre_key,
decoded_msg->dL_NGU_UP_TNLInformation->choice.gTPTunnel->gTP_TEID
.buf,
sizeof(struct in_addr));
memcpy(
&dl_teid.teid_gre_key,
&dl_teid.ipv4_address,
decoded_msg->dL_NGU_UP_TNLInformation->choice.gTPTunnel
->transportLayerAddress.buf,
4);
smreq->req.set_dl_fteid(dl_teid);
Logger::smf_app().debug("gTP_TEID " "0x%" PRIx32 " ",
htonl(dl_teid.teid_gre_key));
Logger::smf_app().debug("uPTransportLayerInformation IP Addr %s",
conv::toString(dl_teid.ipv4_address).c_str());
//list of Qos Flows which have been successfully setup or modified
for (int i = 0;
i < decoded_msg->qosFlowAddOrModifyResponseList->list.count; i++) {
smreq->req.add_qfi(
(decoded_msg->qosFlowAddOrModifyResponseList->list.array[i])
->qosFlowIdentifier);
if (decoded_msg->qosFlowAddOrModifyResponseList) {
for (int i = 0;
i < decoded_msg->qosFlowAddOrModifyResponseList->list.count;
i++) {
smreq->req.add_qfi(
(decoded_msg->qosFlowAddOrModifyResponseList->list.array[i])
->qosFlowIdentifier);
}
}
//TODO:
//list of QoS Flows which have failed to be modified
//qosFlowFailedToAddOrModifyList
//TODO: list of QoS Flows which have failed to be modified, qosFlowFailedToAddOrModifyList
//TODO: additionalDLQosFlowPerTNLInformation
//need to update UPF accordingly
update_upf = true;
......@@ -2111,8 +2054,6 @@ void smf_context::handle_pdu_session_update_sm_context_request(
int decode_status = smf_n1_n2_inst.decode_n2_sm_information(
decoded_msg, n2_sm_information);
if (decode_status == RETURNerror) {
Logger::smf_api_server().warn("asn_decode failed");
//send error to AMF
Logger::smf_app().warn(
"Decode N2 SM (Ngap_PDUSessionResourceReleaseResponseTransfer) failed!");
problem_details.setCause(
......@@ -2124,19 +2065,8 @@ void smf_context::handle_pdu_session_update_sm_context_request(
return;
}
//don't need to create a procedure to update UPF
//Send ITTI to N11 to send PDUSession_UpdateSMContext Response to AMF
//No need to create N1/N2 Container
sm_context_resp_pending->session_procedure_type = procedure_type;
Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name());
int ret = itti_inst->send_msg(sm_context_resp_pending);
if (RETURNok != ret) {
Logger::smf_app().error(
"Could not send ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name());
}
//don't need to create a procedure to update UPF
}
break;
......@@ -2199,7 +2129,6 @@ void smf_context::handle_pdu_session_update_sm_context_request(
std::shared_ptr<smf_procedure> sproc = std::shared_ptr<smf_procedure>(proc);
proc->session_procedure_type = procedure_type;
//smreq->req = sm_context_req_msg;
insert_procedure(sproc);
if (proc->run(smreq, sm_context_resp_pending, shared_from_this())) {
// error !
......@@ -2258,6 +2187,15 @@ void smf_context::handle_pdu_session_update_sm_context_request(
return;
}
} else {
Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name());
int ret = itti_inst->send_msg(sm_context_resp_pending);
if (RETURNok != ret) {
Logger::smf_app().error(
"Could not send ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name());
}
}
//TODO, Step 6
......@@ -2269,7 +2207,6 @@ void smf_context::handle_pdu_session_update_sm_context_request(
}
//-------------------------------------------------------------------------------------
void smf_context::handle_pdu_session_release_sm_context_request(
std::shared_ptr<itti_n11_release_sm_context_request> smreq) {
......@@ -2278,52 +2215,48 @@ void smf_context::handle_pdu_session_release_sm_context_request(
bool update_upf = false;
//Step 1. get DNN, SMF PDU session context. At this stage, dnn_context and pdu_session must be existed
std::shared_ptr<dnn_context> sd = { };
std::shared_ptr<smf_pdu_session> sp = { };
bool find_dnn = find_dnn_context(smreq->req.get_snssai(),
smreq->req.get_dnn(), sd);
bool find_pdu = false;
if (find_dnn) {
find_pdu = sd.get()->find_pdu_session(
smreq->req.get_pdu_session_id(), sp);
}
if (!find_dnn or !find_pdu) {
//error, send reply to AMF with error code "Context Not Found"
Logger::smf_app().warn("DNN or PDU session context does not exist!");
smf_n11_inst->send_pdu_session_release_sm_context_response(
smreq->http_response,
Pistache::Http::Code::Not_Found);
return;
}
//we need to store HttpResponse and session-related information to be used when receiving the response from UPF
itti_n11_release_sm_context_response *n11_sm_context_resp =
new itti_n11_release_sm_context_response(TASK_SMF_APP, TASK_SMF_N11,
//Step 1. get DNN, SMF PDU session context. At this stage, dnn_context and pdu_session must be existed
std::shared_ptr<dnn_context> sd = { };
std::shared_ptr<smf_pdu_session> sp = { };
bool find_dnn = find_dnn_context(smreq->req.get_snssai(),
smreq->req.get_dnn(), sd);
bool find_pdu = false;
if (find_dnn) {
find_pdu = sd.get()->find_pdu_session(smreq->req.get_pdu_session_id(), sp);
}
if (!find_dnn or !find_pdu) {
//error, send reply to AMF with error code "Context Not Found"
Logger::smf_app().warn("DNN or PDU session context does not exist!");
smf_n11_inst->send_pdu_session_release_sm_context_response(
smreq->http_response, Pistache::Http::Code::Not_Found);
return;
}
//we need to store HttpResponse and session-related information to be used when receiving the response from UPF
itti_n11_release_sm_context_response *n11_sm_context_resp =
new itti_n11_release_sm_context_response(TASK_SMF_APP, TASK_SMF_N11,
smreq->http_response);
std::shared_ptr<itti_n11_release_sm_context_response> sm_context_resp_pending =
std::shared_ptr<itti_n11_release_sm_context_response>(n11_sm_context_resp);
n11_sm_context_resp->res.set_supi(smreq->req.get_supi());
n11_sm_context_resp->res.set_supi_prefix(
smreq->req.get_supi_prefix());
n11_sm_context_resp->res.set_cause(REQUEST_ACCEPTED);
n11_sm_context_resp->res.set_pdu_session_id(
smreq->req.get_pdu_session_id());
n11_sm_context_resp->res.set_snssai(smreq->req.get_snssai());
n11_sm_context_resp->res.set_dnn(smreq->req.get_dnn());
session_release_sm_context_procedure *proc =
new session_release_sm_context_procedure(sp);
std::shared_ptr<smf_procedure> sproc = std::shared_ptr<smf_procedure>(proc);
insert_procedure(sproc);
if (proc->run(smreq, sm_context_resp_pending, shared_from_this())) {
// error !
Logger::smf_app().info(
"PDU Release SM Context Request procedure failed");
}
std::shared_ptr<itti_n11_release_sm_context_response> sm_context_resp_pending =
std::shared_ptr<itti_n11_release_sm_context_response>(
n11_sm_context_resp);
n11_sm_context_resp->res.set_supi(smreq->req.get_supi());
n11_sm_context_resp->res.set_supi_prefix(smreq->req.get_supi_prefix());
n11_sm_context_resp->res.set_cause(REQUEST_ACCEPTED);
n11_sm_context_resp->res.set_pdu_session_id(smreq->req.get_pdu_session_id());
n11_sm_context_resp->res.set_snssai(smreq->req.get_snssai());
n11_sm_context_resp->res.set_dnn(smreq->req.get_dnn());
session_release_sm_context_procedure *proc =
new session_release_sm_context_procedure(sp);
std::shared_ptr<smf_procedure> sproc = std::shared_ptr<smf_procedure>(proc);
insert_procedure(sproc);
if (proc->run(smreq, sm_context_resp_pending, shared_from_this())) {
// error !
Logger::smf_app().info("PDU Release SM Context Request procedure failed");
}
}
......
......@@ -57,6 +57,9 @@ extern "C" {
#include "Ngap_PDUSessionResourceReleaseCommandTransfer.h"
#include "dynamic_memory_check.h"
#include "Ngap_PDUSessionResourceReleaseResponseTransfer.h"
#include "Ngap_QosFlowAddOrModifyResponseItem.h"
#include "Ngap_QosFlowAddOrModifyResponseList.h"
}
#define BUF_LEN 512
......@@ -1330,6 +1333,105 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg,
}
break;
case n2_sm_info_type_e::PDU_RES_MOD_RSP: {
//PDU Session Resource Modify Response Transfer IE
//for testing purpose
Logger::smf_app().debug(
"[Create N2 SM Information] NGAP PDU Session Resource Modify Response Transfer");
//struct Ngap_UPTransportLayerInformation *dL_NGU_UP_TNLInformation; /* OPTIONAL */
//struct Ngap_UPTransportLayerInformation *uL_NGU_UP_TNLInformation; /* OPTIONAL */
//struct Ngap_QosFlowAddOrModifyResponseList *qosFlowAddOrModifyResponseList; /* OPTIONAL */
//struct Ngap_QosFlowPerTNLInformationList *additionalDLQosFlowPerTNLInformation; /* OPTIONAL */
// struct Ngap_QosFlowListWithCause *qosFlowFailedToAddOrModifyList; /* OPTIONAL */
Ngap_PDUSessionResourceModifyResponseTransfer_t *ngap_resource_response_transfer =
nullptr;
ngap_resource_response_transfer =
(Ngap_PDUSessionResourceModifyResponseTransfer_t*) calloc(
1, sizeof(Ngap_PDUSessionResourceModifyResponseTransfer_t));
ngap_resource_response_transfer->dL_NGU_UP_TNLInformation = (Ngap_UPTransportLayerInformation *) calloc (1, sizeof (Ngap_UPTransportLayerInformation));
ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->present = Ngap_UPTransportLayerInformation_PR_gTPTunnel;
ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel = (Ngap_GTPTunnel_t*) calloc(1, sizeof(Ngap_GTPTunnel_t));
ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel->transportLayerAddress
.size = 4;
ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel->transportLayerAddress
.buf = (uint8_t*) calloc(4, sizeof(uint8_t));
ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel->transportLayerAddress
.buf[0] = 0xc0;
ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel->transportLayerAddress
.buf[1] = 0xa8;
ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel->transportLayerAddress
.buf[2] = 0xf8;
ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel->transportLayerAddress
.buf[3] = 0x9f;
ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel->transportLayerAddress
.bits_unused = 0;
ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel->gTP_TEID.size = 4;
ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel->gTP_TEID.buf =
(uint8_t*) calloc(4, sizeof(uint8_t));
ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel->gTP_TEID.buf[0] = 0x00;
ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel->gTP_TEID.buf[1] = 0x00;
ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel->gTP_TEID.buf[2] = 0x00;
ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel->gTP_TEID.buf[3] = 0x01;
ngap_resource_response_transfer->qosFlowAddOrModifyResponseList = (Ngap_QosFlowAddOrModifyResponseList_t*) calloc(1, sizeof (Ngap_QosFlowAddOrModifyResponseList_t));
Ngap_QosFlowAddOrModifyResponseItem *qosFlowAddOrModifyResponseItem = nullptr;
qosFlowAddOrModifyResponseItem = (Ngap_QosFlowAddOrModifyResponseItem*) calloc (1, sizeof(Ngap_QosFlowAddOrModifyResponseItem));
qosFlowAddOrModifyResponseItem->qosFlowIdentifier = 60;
ASN_SEQUENCE_ADD(
&ngap_resource_response_transfer->qosFlowAddOrModifyResponseList->list,
qosFlowAddOrModifyResponseItem);
//encode
size_t buffer_size = 512;
char *buffer = (char*) calloc(1, buffer_size);
asn_enc_rval_t er = aper_encode_to_buffer(
&asn_DEF_Ngap_PDUSessionResourceModifyResponseTransfer, nullptr,
ngap_resource_response_transfer, (void*) buffer, buffer_size);
if (er.encoded < 0) {
Logger::smf_app().warn(
"[Create N2 SM Information] NGAP PDU Session Resource Modify Response Transfer encode failed, er.encoded: %d",
er.encoded);
return;
}
Logger::smf_app().debug("N2 SM buffer data: ");
for (int i = 0; i < er.encoded; i++)
printf("%02x ", (char) buffer[i]);
Logger::smf_app().debug(" (%d bytes) \n", er.encoded);
std::string ngap_message((char*) buffer, er.encoded);
ngap_msg_str = ngap_message;
//free memory
free_wrapper(
(void**) &ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel->transportLayerAddress
.buf);
free_wrapper(
(void**) &ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel->gTP_TEID.buf);
free_wrapper(
(void**) &ngap_resource_response_transfer->dL_NGU_UP_TNLInformation->choice.gTPTunnel);
free_wrapper((void**) &qosFlowAddOrModifyResponseItem);
free_wrapper((void**) &ngap_resource_response_transfer->qosFlowAddOrModifyResponseList);
free_wrapper((void**) &ngap_resource_response_transfer);
free_wrapper((void**) &buffer);
}
break;
//PDU Session Resource Release Command Transfer
case n2_sm_info_type_e::PDU_RES_REL_CMD: {
//PDU Session Resource Release Command Transfer IE
......@@ -1513,7 +1615,7 @@ int smf_n1_n2::decode_n2_sm_information(
free_wrapper((void**) &data);
if (rc.code != RC_OK) {
Logger::smf_api_server().warn("asn_decode failed with code %d", rc.code);
Logger::smf_app().warn("asn_decode failed with code %d", rc.code);
return RETURNerror ;
}
return RETURNok ;
......@@ -1542,7 +1644,7 @@ int smf_n1_n2::decode_n2_sm_information(
free_wrapper((void**) &data);
if (rc.code != RC_OK) {
Logger::smf_api_server().warn("asn_decode failed with code %d", rc.code);
Logger::smf_app().warn("asn_decode failed with code %d", rc.code);
return RETURNerror ;
}
......@@ -1572,7 +1674,7 @@ int smf_n1_n2::decode_n2_sm_information(
free_wrapper((void**) &data);
if (rc.code != RC_OK) {
Logger::smf_api_server().warn("asn_decode failed with code %d", rc.code);
Logger::smf_app().warn("asn_decode failed with code %d", rc.code);
return RETURNerror ;
}
......
......@@ -290,10 +290,10 @@ void send_pdu_session_update_sm_context_establishment(
ENCODE_U8(buffer, 0x00, size);
ENCODE_U8(buffer + size, 0x03, size);
ENCODE_U8(buffer + size, 0xe0, size);
ENCODE_U8(buffer + size, 0xac, size); //uPTransportLayerInformation IP Addr 172.10.5.1: 172.
ENCODE_U8(buffer + size, 0x0a, size); //10
ENCODE_U8(buffer + size, 0x05, size); //.5
ENCODE_U8(buffer + size, 0x01, size); //.1
ENCODE_U8(buffer + size, 0xac, size); //uPTransportLayerInformation IP Addr 172.16.3.103: 172.
ENCODE_U8(buffer + size, 0x10, size); //16
ENCODE_U8(buffer + size, 0x03, size); //.3
ENCODE_U8(buffer + size, 0x67, size); //.103
ENCODE_U8(buffer + size, 0x00, size); //gTP_TEID 00 00 00 01: 00
ENCODE_U8(buffer + size, 0x00, size); //00
ENCODE_U8(buffer + size, 0x00, size); //00
......@@ -496,6 +496,207 @@ void send_pdu_session_modification_request_step1(std::string smf_ip_address) {
free(buffer);
}
//------------------------------------------------------------------------------
void send_pdu_session_modification_request_step2(std::string smf_ip_address) {
std::cout
<< "[AMF N11] PDU Session Modification procedure (SM Context Update, step 2)"
<< std::endl;
nlohmann::json pdu_session_modification;
//encode PDU Session Resource Modify Response Transfer IE
size_t buffer_size = 128;
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
//ENCODE_U8(buffer, 0x00, size);
ENCODE_U8(buffer + size, 0x50, size);
ENCODE_U8(buffer + size, 0x03, size);
ENCODE_U8(buffer + size, 0xe0, size); //Id dL_NGU_UP_TNLInformation
ENCODE_U8(buffer + size, 0xac, size); //Transport Layer Address 172.16.3.101: 172
ENCODE_U8(buffer + size, 0x10, size); //Transport Layer Address 172.16.3.101: 16
ENCODE_U8(buffer + size, 0x03, size); //Transport Layer Address 172.16.3.101: 3
ENCODE_U8(buffer + size, 0x65, size); //Transport Layer Address 172.16.3.101: 101
ENCODE_U8(buffer + size, 0x00, size); //Gtp-teid: 01000000
ENCODE_U8(buffer + size, 0x00, size); //Gtp-teid: 01000000
ENCODE_U8(buffer + size, 0x00, size); //Gtp-teid: 01000000
ENCODE_U8(buffer + size, 0x01, size); //Gtp-teid: 01000000
ENCODE_U8(buffer + size, 0x00, size); //QoSFlowAddorModifyResponseList
ENCODE_U8(buffer + size, 0x78, size); //60: QFI
/*
struct Ngap_UPTransportLayerInformation *dL_NGU_UP_TNLInformation;
struct Ngap_UPTransportLayerInformation *uL_NGU_UP_TNLInformation;
struct Ngap_QosFlowAddOrModifyResponseList *qosFlowAddOrModifyResponseList;
struct Ngap_QosFlowPerTNLInformationList *additionalDLQosFlowPerTNLInformation;
struct Ngap_QosFlowListWithCause *qosFlowFailedToAddOrModifyList;
struct Ngap_ProtocolExtensionContainer *iE_Extensions;
*/
std::cout << "Buffer: " << std::endl;
for (int i = 0; i < size; i++) {
printf("%02x ", buffer[i]);
}
std::cout << "Buffer: " << std::endl;
std::string url = std::string("http://");
url.append(smf_ip_address);
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//Fill the json part
pdu_session_modification["n2SmInfoType"] = "PDU_RES_MOD_RSP"; //"PDU_RES_SETUP_RSP"
pdu_session_modification["n2SmInfo"]["contentId"] = "n2SmMsg"; //NGAP
std::string body;
std::string boundary = "----Boundary";
std::string json_part = pdu_session_modification.dump();
std::string n2_msg(reinterpret_cast<const char*>(buffer), size);
create_multipart_related_content(body, json_part, boundary, n2_msg,
multipart_related_content_part_e::NGAP);
unsigned char *data = (unsigned char*) malloc(body.length() + 1);
memset(data, 0, body.length() + 1);
memcpy((void*) data, (void*) body.c_str(), body.length());
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(
headers, "content-type: multipart/related; boundary=----Boundary");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
nlohmann::json response_data;
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception &e) {
std::cout << "Could not get json data from the response" << std::endl;
}
std::cout
<< "[AMF N11] PDU Session Modification procedure (step 2), response from SMF, Http Code "
<< httpCode << std::endl;
curl_easy_cleanup(curl);
}
curl_global_cleanup();
free(buffer);
}
//------------------------------------------------------------------------------
void send_pdu_session_modification_complete(std::string smf_ip_address) {
std::cout
<< "[AMF N11] PDU Session Modification Complete (Update SM Context): N1 SM - PDU Session Modification Complete"
<< std::endl;
nlohmann::json pdu_session_modification_complete;
//encode PDU Session Modification Complete
size_t buffer_size = 128;
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); //ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, 0x01, size); //PDUSessionIdentity
ENCODE_U8(buffer + size, 0x01, size); //ProcedureTransactionIdentity
ENCODE_U8(buffer + size, 0xcc, size); //MessageType
ENCODE_U8(buffer + size, 0x00, size); //presence
ENCODE_U8(buffer + size, 0x00, size); //Extended protocol configuration options
std::cout << "Buffer: " << std::endl;
for (int i = 0; i < size; i++) {
printf("%02x ", buffer[i]);
}
std::cout << "Buffer: " << std::endl;
std::string url = std::string("http://");
url.append(smf_ip_address);
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//Fill the json part
pdu_session_modification_complete["n1SmMsg"]["contentId"] = "n1SmMsg"; // NAS
std::string body;
std::string boundary = "----Boundary";
std::string json_part = pdu_session_modification_complete.dump();
std::string n1_msg(reinterpret_cast<const char*>(buffer), size);
create_multipart_related_content(body, json_part, boundary, n1_msg,
multipart_related_content_part_e::NAS);
unsigned char *data = (unsigned char*) malloc(body.length() + 1);
memset(data, 0, body.length() + 1);
memcpy((void*) data, (void*) body.c_str(), body.length());
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(
headers, "content-type: multipart/related; boundary=----Boundary");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
nlohmann::json response_data;
try {
response_data = nlohmann::json::parse(*httpData.get());
} catch (nlohmann::json::exception &e) {
std::cout << "Could not get json data from the response" << std::endl;
}
std::cout
<< "[AMF N11] PDU Session Modification Complete, response from SMF, Http Code "
<< httpCode << std::endl;
curl_easy_cleanup(curl);
}
curl_global_cleanup();
free(buffer);
}
//------------------------------------------------------------------------------
void send_pdu_session_release_request(std::string smf_ip_address) {
......@@ -1054,6 +1255,9 @@ int main(int argc, char *argv[]) {
usleep(200000);
//PDU Session Modification
send_pdu_session_modification_request_step1(smf_ip_address);
send_pdu_session_modification_request_step2(smf_ip_address);
send_pdu_session_modification_complete(smf_ip_address);
//PDU Session Release procedure
send_pdu_session_release_request(smf_ip_address);
usleep(200000);
......@@ -1063,7 +1267,7 @@ int main(int argc, char *argv[]) {
usleep(200000);
//Release SM context
send_release_sm_context_request(smf_ip_address);
//send_release_sm_context_request(smf_ip_address);
return 0;
}
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