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

finalize PDU Session Modification procedure (step 2 and 3)

parent 0d1c5fd6
This diff is collapsed.
...@@ -57,6 +57,9 @@ extern "C" { ...@@ -57,6 +57,9 @@ extern "C" {
#include "Ngap_PDUSessionResourceReleaseCommandTransfer.h" #include "Ngap_PDUSessionResourceReleaseCommandTransfer.h"
#include "dynamic_memory_check.h" #include "dynamic_memory_check.h"
#include "Ngap_PDUSessionResourceReleaseResponseTransfer.h" #include "Ngap_PDUSessionResourceReleaseResponseTransfer.h"
#include "Ngap_QosFlowAddOrModifyResponseItem.h"
#include "Ngap_QosFlowAddOrModifyResponseList.h"
} }
#define BUF_LEN 512 #define BUF_LEN 512
...@@ -1330,6 +1333,105 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg, ...@@ -1330,6 +1333,105 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg,
} }
break; 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 //PDU Session Resource Release Command Transfer
case n2_sm_info_type_e::PDU_RES_REL_CMD: { case n2_sm_info_type_e::PDU_RES_REL_CMD: {
//PDU Session Resource Release Command Transfer IE //PDU Session Resource Release Command Transfer IE
...@@ -1513,7 +1615,7 @@ int smf_n1_n2::decode_n2_sm_information( ...@@ -1513,7 +1615,7 @@ int smf_n1_n2::decode_n2_sm_information(
free_wrapper((void**) &data); free_wrapper((void**) &data);
if (rc.code != RC_OK) { 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 RETURNerror ;
} }
return RETURNok ; return RETURNok ;
...@@ -1542,7 +1644,7 @@ int smf_n1_n2::decode_n2_sm_information( ...@@ -1542,7 +1644,7 @@ int smf_n1_n2::decode_n2_sm_information(
free_wrapper((void**) &data); free_wrapper((void**) &data);
if (rc.code != RC_OK) { 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 RETURNerror ;
} }
...@@ -1572,7 +1674,7 @@ int smf_n1_n2::decode_n2_sm_information( ...@@ -1572,7 +1674,7 @@ int smf_n1_n2::decode_n2_sm_information(
free_wrapper((void**) &data); free_wrapper((void**) &data);
if (rc.code != RC_OK) { 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 RETURNerror ;
} }
......
...@@ -290,10 +290,10 @@ void send_pdu_session_update_sm_context_establishment( ...@@ -290,10 +290,10 @@ void send_pdu_session_update_sm_context_establishment(
ENCODE_U8(buffer, 0x00, size); ENCODE_U8(buffer, 0x00, size);
ENCODE_U8(buffer + size, 0x03, size); ENCODE_U8(buffer + size, 0x03, size);
ENCODE_U8(buffer + size, 0xe0, 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, 0xac, size); //uPTransportLayerInformation IP Addr 172.16.3.103: 172.
ENCODE_U8(buffer + size, 0x0a, size); //10 ENCODE_U8(buffer + size, 0x10, size); //16
ENCODE_U8(buffer + size, 0x05, size); //.5 ENCODE_U8(buffer + size, 0x03, size); //.3
ENCODE_U8(buffer + size, 0x01, size); //.1 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); //gTP_TEID 00 00 00 01: 00
ENCODE_U8(buffer + size, 0x00, size); //00 ENCODE_U8(buffer + size, 0x00, size); //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) { ...@@ -496,6 +496,207 @@ void send_pdu_session_modification_request_step1(std::string smf_ip_address) {
free(buffer); 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) { void send_pdu_session_release_request(std::string smf_ip_address) {
...@@ -1054,6 +1255,9 @@ int main(int argc, char *argv[]) { ...@@ -1054,6 +1255,9 @@ int main(int argc, char *argv[]) {
usleep(200000); usleep(200000);
//PDU Session Modification //PDU Session Modification
send_pdu_session_modification_request_step1(smf_ip_address); 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 //PDU Session Release procedure
send_pdu_session_release_request(smf_ip_address); send_pdu_session_release_request(smf_ip_address);
usleep(200000); usleep(200000);
...@@ -1063,7 +1267,7 @@ int main(int argc, char *argv[]) { ...@@ -1063,7 +1267,7 @@ int main(int argc, char *argv[]) {
usleep(200000); usleep(200000);
//Release SM context //Release SM context
send_release_sm_context_request(smf_ip_address); //send_release_sm_context_request(smf_ip_address);
return 0; 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