Commit 9dddb5c1 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

fix issues for encoding/decoding QoS Rules (PDU Session Modification)

parent 878e3e11
...@@ -6,84 +6,107 @@ ...@@ -6,84 +6,107 @@
#include "TLVDecoder.h" #include "TLVDecoder.h"
#include "QOSRules.h" #include "QOSRules.h"
int encode_qos_rules ( QOSRules qosrules, uint8_t iei, uint8_t * buffer, uint32_t len ) int encode_qos_rules(QOSRules qosrules, uint8_t iei, uint8_t *buffer,
{ uint32_t len) {
uint8_t *len_qosrule = NULL; uint8_t *len_qosrule = NULL;
uint8_t *len_qosrulesie = NULL; uint8_t *len_qosrulesie = NULL;
uint8_t len_pos_qos_rule = 0; uint8_t len_pos_qos_rule = 0;
uint8_t bitstream = 0; uint8_t bitstream = 0;
uint32_t encoded = 0; uint32_t encoded = 0;
int encode_result = 0; int encode_result = 0;
int i = 0,j = 0; int i = 0, j = 0;
uint32_t temp = 0; uint32_t temp = 0;
CHECK_PDU_POINTER_AND_LENGTH_ENCODER (buffer,((iei > 0) ? QOS_RULES_MINIMUM_LENGTH_TLVE : QOS_RULES_MINIMUM_LENGTH_LVE), len); CHECK_PDU_POINTER_AND_LENGTH_ENCODER(
buffer,
((iei > 0) ? QOS_RULES_MINIMUM_LENGTH_TLVE : QOS_RULES_MINIMUM_LENGTH_LVE),
len);
if (iei > 0) {
if( iei > 0 )
{
*buffer = iei; *buffer = iei;
encoded++; encoded++;
} }
len_qosrulesie = buffer + encoded; len_qosrulesie = buffer + encoded;
encoded += 2; //ENCODE_U16(buffer + encoded, qosrules.lengthofqosrulesie, encoded); encoded += 2; //ENCODE_U16(buffer + encoded, qosrules.lengthofqosrulesie, encoded);
uint8_t len_pos_qos_rulesie = encoded; uint8_t len_pos_qos_rulesie = encoded;
/*
*(buffer + encoded) = qosrules.lengthofqosrulesie/(1<<8);
encoded++;
*(buffer + encoded) = qosrules.lengthofqosrulesie%(1<<8);
encoded++;
*/
for(i = 0; i < qosrules.lengthofqosrulesie; i++) for (i = 0; i < qosrules.lengthofqosrulesie; i++) {
{ ENCODE_U8(buffer + encoded, qosrules.qosrulesie[i].qosruleidentifer,
ENCODE_U8(buffer + encoded, qosrules.qosrulesie[i].qosruleidentifer, encoded); encoded);
len_qosrule = buffer + encoded; len_qosrule = buffer + encoded;
encoded++; encoded++;
encoded++; encoded++;
len_pos_qos_rule = encoded; len_pos_qos_rule = encoded;
bitstream = (uint8_t)(qosrules.qosrulesie[i].ruleoperationcode << 5); bitstream = (uint8_t) (qosrules.qosrulesie[i].ruleoperationcode << 5);
bitstream |= (uint8_t)(qosrules.qosrulesie[i].dqrbit << 4); bitstream |= (uint8_t) (qosrules.qosrulesie[i].dqrbit << 4);
bitstream |= (uint8_t)qosrules.qosrulesie[i].numberofpacketfilters; bitstream |= (uint8_t) qosrules.qosrulesie[i].numberofpacketfilters;
ENCODE_U8(buffer+encoded,bitstream,encoded); ENCODE_U8(buffer + encoded, bitstream, encoded);
if((bitstream >> 5) == MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS) if ((bitstream >> 5) == MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS) {
{ for (j = 0; j < (bitstream & 0x0f); j++) {
for(j = 0; j < (bitstream & 0x0f); j++) ENCODE_U8(
{ buffer + encoded,
ENCODE_U8(buffer + encoded, (uint8_t)qosrules.qosrulesie[i].packetfilterlist.modifyanddelete[j].packetfilteridentifier, encoded); (uint8_t )qosrules.qosrulesie[i].packetfilterlist.modifyanddelete[j]
.packetfilteridentifier,
encoded);
} }
ENCODE_U8(buffer + encoded, qosrules.qosrulesie[i].qosruleprecedence, encoded); ENCODE_U8(buffer + encoded, qosrules.qosrulesie[i].qosruleprecedence,
ENCODE_U8(buffer + encoded, (uint8_t)((qosrules.qosrulesie[i].segregation<<6) | (qosrules.qosrulesie[i].qosflowidentifer & 0x3f)), encoded); encoded);
} ENCODE_U8(
else if(((bitstream >> 5) == CREATE_NEW_QOS_RULE) || ((bitstream >> 5) == MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS) || ((bitstream >> 5) == MODIFY_EXISTING_QOS_RULE_AND_REPLACE_ALL_PACKET_FILTERS)) buffer + encoded,
{ (uint8_t )((qosrules.qosrulesie[i].segregation << 6)
for(j = 0; j < (bitstream & 0x0f); j++) | (qosrules.qosrulesie[i].qosflowidentifer & 0x3f)),
{ encoded);
ENCODE_U8(buffer + encoded, (uint8_t)((qosrules.qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace[j].packetfilterdirection << 4)|(qosrules.qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace[j].packetfilteridentifier & 0x0f)),encoded); } else if (((bitstream >> 5) == CREATE_NEW_QOS_RULE)
|| ((bitstream >> 5) == MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS)
|| ((bitstream >> 5)
== MODIFY_EXISTING_QOS_RULE_AND_REPLACE_ALL_PACKET_FILTERS)) {
for (j = 0; j < (bitstream & 0x0f); j++) {
ENCODE_U8(
buffer + encoded,
(uint8_t )((qosrules.qosrulesie[i].packetfilterlist
.create_modifyandadd_modifyandreplace[j].packetfilterdirection
<< 4)
| (qosrules.qosrulesie[i].packetfilterlist
.create_modifyandadd_modifyandreplace[j]
.packetfilteridentifier & 0x0f)),
encoded);
uint8_t *len_packetfiltercontents = buffer + encoded; uint8_t *len_packetfiltercontents = buffer + encoded;
encoded++; encoded++;
ENCODE_U8(buffer + encoded, qosrules.qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace[j].packetfiltercontents.component_type, encoded); ENCODE_U8(
buffer + encoded,
if(qosrules.qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace[j].packetfiltercontents.component_type != QOS_RULE_MATCHALL_TYPE) qosrules.qosrulesie[i].packetfilterlist
{ .create_modifyandadd_modifyandreplace[j].packetfiltercontents
if ((encode_result = encode_bstring (qosrules.qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace[j].packetfiltercontents.component_value, buffer + encoded, len - encoded)) < 0) .component_type,
encoded);
if (qosrules.qosrulesie[i].packetfilterlist
.create_modifyandadd_modifyandreplace[j].packetfiltercontents
.component_type != QOS_RULE_MATCHALL_TYPE) {
if ((encode_result = encode_bstring(
qosrules.qosrulesie[i].packetfilterlist
.create_modifyandadd_modifyandreplace[j].packetfiltercontents
.component_value,
buffer + encoded, len - encoded)) < 0)
return encode_result; return encode_result;
else else
encoded += encode_result; encoded += encode_result;
} }
*len_packetfiltercontents = encode_result+1; *len_packetfiltercontents = encode_result + 1;
} }
ENCODE_U8(buffer + encoded, qosrules.qosrulesie[i].qosruleprecedence, encoded); ENCODE_U8(buffer + encoded, qosrules.qosrulesie[i].qosruleprecedence,
ENCODE_U8(buffer + encoded, (uint8_t)((qosrules.qosrulesie[i].segregation<<6) | (qosrules.qosrulesie[i].qosflowidentifer & 0x3f)), encoded); encoded);
ENCODE_U8(
buffer + encoded,
(uint8_t )((qosrules.qosrulesie[i].segregation << 6)
| (qosrules.qosrulesie[i].qosflowidentifer & 0x3f)),
encoded);
} }
//len of qos rule //len of qos rule
...@@ -95,118 +118,129 @@ int encode_qos_rules ( QOSRules qosrules, uint8_t iei, uint8_t * buffer, uint32_ ...@@ -95,118 +118,129 @@ int encode_qos_rules ( QOSRules qosrules, uint8_t iei, uint8_t * buffer, uint32_
return encoded; return encoded;
} }
int decode_qos_rules ( QOSRules * qosrules, uint8_t iei, uint8_t * buffer, uint32_t len ) int decode_qos_rules(QOSRules *qosrules, uint8_t iei, uint8_t *buffer,
{ uint32_t len) {
int decoded=0; int decoded = 0;
uint16_t ielen=0; uint16_t ielen = 0;
int decode_result = 0; int decode_result = 0;
uint16_t numberrules = 0;
// uint16_t lenqosrule = 0;
uint8_t bitstream = 0; uint8_t bitstream = 0;
int i=0,j=0; int i = 0, j = 0;
if (iei > 0) if (iei > 0) {
{ CHECK_IEI_DECODER(iei, *buffer);
CHECK_IEI_DECODER (iei, *buffer);
decoded++; decoded++;
} }
numberrules = *(buffer + decoded); DECODE_U16(buffer + decoded, qosrules->lengthofqosrulesie, decoded);
decoded++;
numberrules = ( numberrules << 8)+*(buffer + decoded); CHECK_LENGTH_DECODER(len - decoded, qosrules->lengthofqosrulesie);
decoded++;
qosrules->qosrulesie = (QOSRulesIE*) calloc(1, sizeof(QOSRulesIE));
for(i=0;i<numberrules;i++) i = 0;
{ //for(i=0;i<numberrules;i++)
ielen = *(buffer + ielen + 1) + 1; while (decoded < qosrules->lengthofqosrulesie) {
} DECODE_U8(buffer + decoded, qosrules->qosrulesie[i].qosruleidentifer,
decoded);
CHECK_LENGTH_DECODER (len - decoded, ielen); // decoded++;
// decoded++;
qosrules->lengthofqosrulesie = numberrules;
DECODE_U16(buffer + decoded, qosrules->qosrulesie[i].LengthofQoSrule, decoded);
qosrules->qosrulesie = (QOSRulesIE *)calloc(numberrules,sizeof(QOSRulesIE));
for(i=0;i<numberrules;i++) DECODE_U8(buffer + decoded, bitstream, decoded);
{ qosrules->qosrulesie[i].ruleoperationcode = (bitstream >> 5);
DECODE_U8(buffer+decoded,qosrules->qosrulesie[i].qosruleidentifer,decoded); qosrules->qosrulesie[i].dqrbit = (bitstream >> 4) & 0x01;
qosrules->qosrulesie[i].numberofpacketfilters = bitstream & 0x0f;
decoded++;
decoded++; if (qosrules->qosrulesie[i].ruleoperationcode
/*lenqosrule = *(buffer + decoded); == MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS) {
decoded++; qosrules->qosrulesie[i].packetfilterlist.modifyanddelete =
lenqosrule = (lenqosrule << 8)+*(buffer + decoded); (ModifyAndDelete*) calloc(
decoded++; qosrules->qosrulesie[i].numberofpacketfilters,
lenmoment = encoded; sizeof(ModifyAndDelete));
*/ for (j = 0; j < qosrules->qosrulesie[i].numberofpacketfilters; j++) {
DECODE_U8(buffer+decoded,bitstream,decoded); DECODE_U8(buffer + decoded, bitstream, decoded);
qosrules->qosrulesie[i].ruleoperationcode = (bitstream>>5); qosrules->qosrulesie[i].packetfilterlist.modifyanddelete[j]
qosrules->qosrulesie[i].dqrbit = (bitstream>>4)&0x01; .packetfilteridentifier = bitstream & 0x0f;
qosrules->qosrulesie[i].numberofpacketfilters = bitstream&0x0f;
if(qosrules->qosrulesie[i].ruleoperationcode == MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS)
{
qosrules->qosrulesie[i].packetfilterlist.modifyanddelete = (ModifyAndDelete *)calloc(qosrules->qosrulesie[i].numberofpacketfilters,sizeof(ModifyAndDelete));
for(j = 0;j < qosrules->qosrulesie[i].numberofpacketfilters;j++)
{
DECODE_U8(buffer+decoded,bitstream,decoded);
qosrules->qosrulesie[i].packetfilterlist.modifyanddelete[j].packetfilteridentifier = bitstream&0x0f;
} }
DECODE_U8(buffer+decoded,bitstream,decoded); DECODE_U8(buffer + decoded, bitstream, decoded); //QoS rule precedence
qosrules->qosrulesie[i].qosruleprecedence = bitstream; qosrules->qosrulesie[i].qosruleprecedence = bitstream;
DECODE_U8(buffer+decoded,bitstream,decoded); DECODE_U8(buffer + decoded, bitstream, decoded); //QoS flow identifier (QFI)
qosrules->qosrulesie[i].segregation = (bitstream>>6)&0x01; qosrules->qosrulesie[i].segregation = (bitstream >> 6) & 0x01;
qosrules->qosrulesie[i].qosflowidentifer = bitstream&0x3f; qosrules->qosrulesie[i].qosflowidentifer = bitstream & 0x3f;
} } else if ((qosrules->qosrulesie[i].ruleoperationcode == CREATE_NEW_QOS_RULE)
else if((qosrules->qosrulesie[i].ruleoperationcode == CREATE_NEW_QOS_RULE) || (qosrules->qosrulesie[i].ruleoperationcode == MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS) || (qosrules->qosrulesie[i].ruleoperationcode == MODIFY_EXISTING_QOS_RULE_AND_REPLACE_ALL_PACKET_FILTERS)) || (qosrules->qosrulesie[i].ruleoperationcode
{ == MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS)
qosrules->qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace = (Create_ModifyAndAdd_ModifyAndReplace *)calloc(qosrules->qosrulesie[i].numberofpacketfilters,sizeof(Create_ModifyAndAdd_ModifyAndReplace)); || (qosrules->qosrulesie[i].ruleoperationcode
for(j = 0;j < qosrules->qosrulesie[i].numberofpacketfilters;j++) == MODIFY_EXISTING_QOS_RULE_AND_REPLACE_ALL_PACKET_FILTERS)) {
{ qosrules->qosrulesie[i].packetfilterlist
DECODE_U8(buffer+decoded,bitstream,decoded); .create_modifyandadd_modifyandreplace =
qosrules->qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace[j].packetfilterdirection = (bitstream>>4)&0x03; (Create_ModifyAndAdd_ModifyAndReplace*) calloc(
qosrules->qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace[j].packetfilteridentifier = bitstream&0x0f; qosrules->qosrulesie[i].numberofpacketfilters,
sizeof(Create_ModifyAndAdd_ModifyAndReplace));
uint8_t *lenghtofpacketfiltercontents = (uint8_t * ) (*(buffer + decoded) - 1); for (j = 0; j < qosrules->qosrulesie[i].numberofpacketfilters; j++) {
DECODE_U8(buffer + decoded, bitstream, decoded);
qosrules->qosrulesie[i].packetfilterlist
.create_modifyandadd_modifyandreplace[j].packetfilterdirection =
(bitstream >> 4) & 0x03;
qosrules->qosrulesie[i].packetfilterlist
.create_modifyandadd_modifyandreplace[j].packetfilteridentifier =
bitstream & 0x0f;
uint8_t *lenghtofpacketfiltercontents = (uint8_t*) (*(buffer + decoded)
- 1);
decoded++; decoded++;
DECODE_U8(buffer+decoded,bitstream,decoded); DECODE_U8(buffer + decoded, bitstream, decoded);
qosrules->qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace[j].packetfiltercontents.component_type = bitstream; qosrules->qosrulesie[i].packetfilterlist
.create_modifyandadd_modifyandreplace[j].packetfiltercontents
if(qosrules->qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace[j].packetfiltercontents.component_type != QOS_RULE_MATCHALL_TYPE) .component_type = bitstream;
{
if ((decode_result = decode_bstring (&qosrules->qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace[j].packetfiltercontents.component_value, lenghtofpacketfiltercontents, buffer + decoded, len - decoded)) < 0) if (qosrules->qosrulesie[i].packetfilterlist
.create_modifyandadd_modifyandreplace[j].packetfiltercontents
.component_type != QOS_RULE_MATCHALL_TYPE) {
if ((decode_result = decode_bstring(
&qosrules->qosrulesie[i].packetfilterlist
.create_modifyandadd_modifyandreplace[j].packetfiltercontents
.component_value,
lenghtofpacketfiltercontents, buffer + decoded, len - decoded))
< 0)
return decode_result; return decode_result;
else else
decoded += decode_result; decoded += decode_result;
} }
} }
DECODE_U8(buffer+decoded,bitstream,decoded); DECODE_U8(buffer + decoded, bitstream, decoded);
qosrules->qosrulesie[i].qosruleprecedence = bitstream; qosrules->qosrulesie[i].qosruleprecedence = bitstream;
DECODE_U8(buffer+decoded,bitstream,decoded); DECODE_U8(buffer + decoded, bitstream, decoded);
qosrules->qosrulesie[i].segregation = (bitstream>>6)&0x01; qosrules->qosrulesie[i].segregation = (bitstream >> 6) & 0x01;
qosrules->qosrulesie[i].qosflowidentifer = bitstream&0x3f; qosrules->qosrulesie[i].qosflowidentifer = bitstream & 0x3f;
} }
i++;
} }
return decoded; return decoded;
} }
void free_decode_qos_rules(QOSRules * qosrules) void free_decode_qos_rules(QOSRules *qosrules) {
{
int i; int i;
for(i = 0; i < qosrules->lengthofqosrulesie; i++) for (i = 0; i < qosrules->lengthofqosrulesie; i++) {
{ if (qosrules->qosrulesie[i].ruleoperationcode
if(qosrules->qosrulesie[i].ruleoperationcode == MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS) == MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS) {
{
free(qosrules->qosrulesie[i].packetfilterlist.modifyanddelete); free(qosrules->qosrulesie[i].packetfilterlist.modifyanddelete);
qosrules->qosrulesie[i].packetfilterlist.modifyanddelete = NULL; qosrules->qosrulesie[i].packetfilterlist.modifyanddelete = NULL;
} } else if ((qosrules->qosrulesie[i].ruleoperationcode == CREATE_NEW_QOS_RULE)
else if((qosrules->qosrulesie[i].ruleoperationcode == CREATE_NEW_QOS_RULE) || (qosrules->qosrulesie[i].ruleoperationcode == MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS) || (qosrules->qosrulesie[i].ruleoperationcode == MODIFY_EXISTING_QOS_RULE_AND_REPLACE_ALL_PACKET_FILTERS)) || (qosrules->qosrulesie[i].ruleoperationcode
{ == MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS)
free(qosrules->qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace); || (qosrules->qosrulesie[i].ruleoperationcode
qosrules->qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace = NULL; == MODIFY_EXISTING_QOS_RULE_AND_REPLACE_ALL_PACKET_FILTERS)) {
free(
qosrules->qosrulesie[i].packetfilterlist
.create_modifyandadd_modifyandreplace);
qosrules->qosrulesie[i].packetfilterlist
.create_modifyandadd_modifyandreplace = NULL;
} }
} }
free(qosrules->qosrulesie); free(qosrules->qosrulesie);
......
...@@ -1341,9 +1341,6 @@ void smf_context::handle_pdu_session_update_sm_context_request( ...@@ -1341,9 +1341,6 @@ void smf_context::handle_pdu_session_update_sm_context_request(
sm_context_resp_pending->session_procedure_type = sm_context_resp_pending->session_procedure_type =
session_management_procedures_type_e::PDU_SESSION_MODIFICATION_UE_INITIATED_STEP1; session_management_procedures_type_e::PDU_SESSION_MODIFICATION_UE_INITIATED_STEP1;
//step 1. assign the necessary information from pdu_session_modification_request
//to sm_context_req_msg to be used to create N1 SM, N2 SM information
//check if the PDU Session Release Command is already sent for this message (see section 6.3.3.5 @3GPP TS 24.501) //check if the PDU Session Release Command is already sent for this message (see section 6.3.3.5 @3GPP TS 24.501)
if (sp.get()->get_pdu_session_status() if (sp.get()->get_pdu_session_status()
== pdu_session_status_e::PDU_SESSION_INACTIVE_PENDING) { == pdu_session_status_e::PDU_SESSION_INACTIVE_PENDING) {
...@@ -1391,8 +1388,9 @@ void smf_context::handle_pdu_session_update_sm_context_request( ...@@ -1391,8 +1388,9 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//TODO: IntergrityProtectionMaximumDataRate //TODO: IntergrityProtectionMaximumDataRate
//Process QoS rules and Qos Flow descriptions //Process QoS rules and Qos Flow descriptions
uint8_t number_of_rules = decoded_nas_msg.plain.sm uint16_t length_of_rule_ie = decoded_nas_msg.plain.sm
.pdu_session_modification_request.qosrules.lengthofqosrulesie; .pdu_session_modification_request.qosrules.lengthofqosrulesie;
QOSRulesIE *qos_rules_ie = (QOSRulesIE*) calloc(1, sizeof(QOSRulesIE)); QOSRulesIE *qos_rules_ie = (QOSRulesIE*) calloc(1, sizeof(QOSRulesIE));
qos_rules_ie = decoded_nas_msg.plain.sm.pdu_session_modification_request qos_rules_ie = decoded_nas_msg.plain.sm.pdu_session_modification_request
.qosrules.qosrulesie; .qosrules.qosrulesie;
...@@ -1426,12 +1424,17 @@ void smf_context::handle_pdu_session_update_sm_context_request( ...@@ -1426,12 +1424,17 @@ void smf_context::handle_pdu_session_update_sm_context_request(
} }
} }
for (int i = 0; i < number_of_rules; i++) { int i = 0;
int length_of_rule = 0;
while (length_of_rule_ie > 0) {
//for (int i = 0; i < number_of_rules; i++) {
uint8_t rule_id = { 0 }; uint8_t rule_id = { 0 };
QOSRulesIE qos_rule = { }; QOSRulesIE qos_rule = { };
pfcp::qfi_t qfi = { }; pfcp::qfi_t qfi = { };
smf_qos_flow qos_flow = { }; smf_qos_flow qos_flow = { };
length_of_rule = qos_rules_ie[i].LengthofQoSrule;
//If UE requested a new GBR flow //If UE requested a new GBR flow
if ((qos_rules_ie[i].ruleoperationcode == CREATE_NEW_QOS_RULE) if ((qos_rules_ie[i].ruleoperationcode == CREATE_NEW_QOS_RULE)
and (qos_rules_ie[i].segregation == SEGREGATION_REQUESTED)) { and (qos_rules_ie[i].segregation == SEGREGATION_REQUESTED)) {
...@@ -1498,17 +1501,33 @@ void smf_context::handle_pdu_session_update_sm_context_request( ...@@ -1498,17 +1501,33 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//Add new QoS flow //Add new QoS flow
sp.get()->add_qos_flow(qos_flow); sp.get()->add_qos_flow(qos_flow);
//ADD QoS Flow to be updated
qos_flow_context_updated qcu = { };
qcu.set_qfi(pfcp::qfi_t(qos_flow.qfi));
//qcu.set_ul_fteid(flow.ul_fteid);
//qcu.set_dl_fteid(flow.dl_fteid);
qcu.set_qos_profile(qos_flow.qos_profile);
sm_context_resp_pending->res.add_qos_flow_context_updated(qcu);
} else { } else {
qfi.qfi = qos_rules_ie[i].qosflowidentifer; qfi.qfi = qos_rules_ie[i].qosflowidentifer;
sp.get()->get_qos_flow(qfi, qos_flow); sp.get()->get_qos_flow(qfi, qos_flow);
qos_flow.update_qos_rule(qos_rules_ie[i]); qos_flow.update_qos_rule(qos_rules_ie[i]);
//update QoS flow //update QoS flow
sp.get()->add_qos_flow(qos_flow); sp.get()->add_qos_flow(qos_flow);
//ADD QoS Flow to be updated
qos_flow_context_updated qcu = { };
qcu.set_qfi(pfcp::qfi_t(qos_flow.qfi));
//qcu.set_ul_fteid(flow.ul_fteid);
//qcu.set_dl_fteid(flow.dl_fteid);
qcu.set_qos_profile(qos_flow.qos_profile);
sm_context_resp_pending->res.add_qos_flow_context_updated(qcu);
} }
length_of_rule_ie -= (length_of_rule + 3);
} }
free_wrapper((void**) &qos_rules_ie);
free_wrapper((void**) &qos_flow_description);
//TODO: MappedEPSBearerContexts //TODO: MappedEPSBearerContexts
//TODO: ExtendedProtocolConfigurationOptions //TODO: ExtendedProtocolConfigurationOptions
...@@ -1544,16 +1563,18 @@ void smf_context::handle_pdu_session_update_sm_context_request( ...@@ -1544,16 +1563,18 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//Fill the json part //Fill the json part
//N1SM //N1SM
n11_sm_context_resp->res.sm_context_updated_data["n1SmMsg"]["n1MessageClass"] = n11_sm_context_resp->res.sm_context_updated_data["n1MessageContainer"]["n1MessageClass"] =
N1N2_MESSAGE_CLASS; N1N2_MESSAGE_CLASS;
n11_sm_context_resp->res.sm_context_updated_data["n1SmMsg"]["n1MessageContent"]["contentId"] = n11_sm_context_resp->res.sm_context_updated_data["n1MessageContainer"]["n1MessageContent"]["contentId"] =
N1_SM_CONTENT_ID; //part 2 N1_SM_CONTENT_ID; //part 2
n11_sm_context_resp->res.sm_context_updated_data["n2SmInfo"]["n2InformationClass"] = n11_sm_context_resp->res.sm_context_updated_data["n2InfoContainer"]["n2InformationClass"] =
N1N2_MESSAGE_CLASS; N1N2_MESSAGE_CLASS;
n11_sm_context_resp->res.sm_context_updated_data["n2SmInfo"]["n2InfoContent"]["ngapIeType"] = n11_sm_context_resp->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
"PDU_RES_MOD_REQ"; //NGAP message "PDU_RES_MOD_REQ"; //NGAP message
n11_sm_context_resp->res.sm_context_updated_data["n2SmInfo"]["n2InfoContent"]["ngapData"]["contentId"] = n11_sm_context_resp->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] =
N2_SM_CONTENT_ID; //part 3 N2_SM_CONTENT_ID; //part 3
n11_sm_context_resp->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["PduSessionId"] =
n11_sm_context_resp->res.get_pdu_session_id();
//Update PDU Session status //Update PDU Session status
sp.get()->set_pdu_session_status( sp.get()->set_pdu_session_status(
...@@ -1575,6 +1596,9 @@ void smf_context::handle_pdu_session_update_sm_context_request( ...@@ -1575,6 +1596,9 @@ void smf_context::handle_pdu_session_update_sm_context_request(
"Could not send ITTI message %s to task TASK_SMF_N11", "Could not send ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name()); sm_context_resp_pending->get_msg_name());
} }
free_wrapper((void**) &qos_rules_ie);
free_wrapper((void**) &qos_flow_description);
} }
break; break;
...@@ -1602,16 +1626,15 @@ void smf_context::handle_pdu_session_update_sm_context_request( ...@@ -1602,16 +1626,15 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//stop T3591 //stop T3591
itti_inst->timer_remove(sp.get()->timer_T3591); itti_inst->timer_remove(sp.get()->timer_T3591);
/* //Send PDUSession_UpdateSMContext Response to AMF
/* //Send PDUSession_UpdateSMContext Response to AMF //No need to create N1/N2 Container
//No need to create N1/N2 Container Logger::smf_app().info(
Logger::smf_app().info( "PDU Session Modification UE-initiated (Step 3)");
"PDU Session Modification UE-initiated (Step 3)"); smContextUpdatedData = { };
smContextUpdatedData = { }; smf_n11_inst->send_pdu_session_update_sm_context_response(
smf_n11_inst->send_pdu_session_update_sm_context_response( n11_sm_context_resp->http_response, smContextUpdatedData,
n11_sm_context_resp->http_response, smContextUpdatedData, Pistache::Http::Code::No_Content);
Pistache::Http::Code::No_Content); */
*/
//don't need to create a procedure to update UPF //don't need to create a procedure to update UPF
//Send ITTI to N11 to send PDUSession_UpdateSMContext Response to AMF //Send ITTI to N11 to send PDUSession_UpdateSMContext Response to AMF
...@@ -1671,15 +1694,15 @@ void smf_context::handle_pdu_session_update_sm_context_request( ...@@ -1671,15 +1694,15 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//stop T3591 //stop T3591
itti_inst->timer_remove(sp.get()->timer_T3591); itti_inst->timer_remove(sp.get()->timer_T3591);
/* //Send PDUSession_UpdateSMContext Response to AMF /* //Send PDUSession_UpdateSMContext Response to AMF
//No need to create N1/N2 Container //No need to create N1/N2 Container
Logger::smf_app().info( Logger::smf_app().info(
"PDU Session Modification UE-initiated (Step 3)"); "PDU Session Modification UE-initiated (Step 3)");
smContextUpdatedData = { }; smContextUpdatedData = { };
smf_n11_inst->send_pdu_session_update_sm_context_response( smf_n11_inst->send_pdu_session_update_sm_context_response(
n11_sm_context_resp->http_response, smContextUpdatedData, n11_sm_context_resp->http_response, smContextUpdatedData,
Pistache::Http::Code::No_Content); Pistache::Http::Code::No_Content);
*/ */
//don't need to create a procedure to update UPF //don't need to create a procedure to update UPF
//Send ITTI to N11 to send PDUSession_UpdateSMContext Response to AMF //Send ITTI to N11 to send PDUSession_UpdateSMContext Response to AMF
...@@ -1755,51 +1778,51 @@ void smf_context::handle_pdu_session_update_sm_context_request( ...@@ -1755,51 +1778,51 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//Release the resources related to this PDU Session (in Procedure) //Release the resources related to this PDU Session (in Procedure)
//find DNN context //find DNN context
/* std::shared_ptr<dnn_context> sd = { }; /* std::shared_ptr<dnn_context> sd = { };
if ((!find_dnn_context(sm_context_req_msg.get_snssai(), if ((!find_dnn_context(sm_context_req_msg.get_snssai(),
sm_context_req_msg.get_dnn(), sd)) sm_context_req_msg.get_dnn(), sd))
or (nullptr == sd.get())) { or (nullptr == sd.get())) {
Logger::smf_app().warn( Logger::smf_app().warn(
"Could not find the context for this PDU session"); "Could not find the context for this PDU session");
//create PDU Session Release Reject and send to UE //create PDU Session Release Reject and send to UE
problem_details.setCause( problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]); pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]);
smContextUpdateError.setError(problem_details); smContextUpdateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID); refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData); smContextUpdateError.setN1SmMsg(refToBinaryData);
smf_n1_n2_inst.create_n1_sm_container( smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg, PDU_SESSION_RELEASE_REJECT, n1_sm_msg, sm_context_req_msg, PDU_SESSION_RELEASE_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_111_PROTOCOL_ERROR_UNSPECIFIED); cause_value_5gsm_e::CAUSE_111_PROTOCOL_ERROR_UNSPECIFIED);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex); smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_update_sm_context_response( smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError, smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Not_Found, n1_sm_msg_hex); Pistache::Http::Code::Not_Found, n1_sm_msg_hex);
return; return;
} }
//find PDU Session //find PDU Session
std::shared_ptr<smf_pdu_session> sp; std::shared_ptr<smf_pdu_session> sp;
if ((!sd.get()->find_pdu_session( if ((!sd.get()->find_pdu_session(
sm_context_req_msg.get_pdu_session_id(), sp)) sm_context_req_msg.get_pdu_session_id(), sp))
or (nullptr == sp.get())) { or (nullptr == sp.get())) {
Logger::smf_app().warn( Logger::smf_app().warn(
"Could not find the context for this PDU session"); "Could not find the context for this PDU session");
//create PDU Session Release Reject and send to UE //create PDU Session Release Reject and send to UE
problem_details.setCause( problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]); pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]);
smContextUpdateError.setError(problem_details); smContextUpdateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID); refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData); smContextUpdateError.setN1SmMsg(refToBinaryData);
smf_n1_n2_inst.create_n1_sm_container( smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg, PDU_SESSION_RELEASE_REJECT, n1_sm_msg, sm_context_req_msg, PDU_SESSION_RELEASE_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_43_INVALID_PDU_SESSION_IDENTITY); cause_value_5gsm_e::CAUSE_43_INVALID_PDU_SESSION_IDENTITY);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex); smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_update_sm_context_response( smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError, smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Not_Found, n1_sm_msg_hex); Pistache::Http::Code::Not_Found, n1_sm_msg_hex);
return; return;
} }
*/ */
//get the associated QoS flows: to be used for PFCP Session Modification procedure //get the associated QoS flows: to be used for PFCP Session Modification procedure
std::vector<smf_qos_flow> qos_flows; std::vector<smf_qos_flow> qos_flows;
sp.get()->get_qos_flows(qos_flows); sp.get()->get_qos_flows(qos_flows);
...@@ -1846,11 +1869,11 @@ void smf_context::handle_pdu_session_update_sm_context_request( ...@@ -1846,11 +1869,11 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//Stop timer T3592 //Stop timer T3592
itti_inst->timer_remove(sp.get()->timer_T3592); itti_inst->timer_remove(sp.get()->timer_T3592);
/* //send response to AMF /* //send response to AMF
smf_n11_inst->send_pdu_session_update_sm_context_response( smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdatedData, smreq->http_response, smContextUpdatedData,
Pistache::Http::Code::No_Content); Pistache::Http::Code::No_Content);
*/ */
//don't need to create a procedure to update UPF //don't need to create a procedure to update UPF
//Send ITTI to N11 to send PDUSession_UpdateSMContext Response to AMF //Send ITTI to N11 to send PDUSession_UpdateSMContext Response to AMF
...@@ -1865,22 +1888,21 @@ void smf_context::handle_pdu_session_update_sm_context_request( ...@@ -1865,22 +1888,21 @@ void smf_context::handle_pdu_session_update_sm_context_request(
sm_context_resp_pending->get_msg_name()); sm_context_resp_pending->get_msg_name());
} }
//TODO: SMF invokes Nsmf_PDUSession_SMContextStatusNotify to notify AMF that the SM context for this PDU Session is released //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: 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 //TODO: SMF unsubscribes from Session Management Subscription data changes notification from UDM by invoking Numd_SDM_Unsubscribe
//find dnn context //find dnn context
/* std::shared_ptr<dnn_context> sd = { }; /* std::shared_ptr<dnn_context> sd = { };
bool find_dnn = find_dnn_context(sm_context_req_msg.get_snssai(), bool find_dnn = find_dnn_context(sm_context_req_msg.get_snssai(),
sm_context_req_msg.get_dnn(), sd); sm_context_req_msg.get_dnn(), sd);
//At this step, this context should be existed //At this step, this context should be existed
if (nullptr == sd.get()) { if (nullptr == sd.get()) {
Logger::smf_app().debug( Logger::smf_app().debug(
"DNN context (dnn_in_use %s) is not existed yet!", "DNN context (dnn_in_use %s) is not existed yet!",
sm_context_req_msg.get_dnn().c_str()); sm_context_req_msg.get_dnn().c_str());
//TODO: //TODO:
} }
*/ */
if (sd.get()->get_number_pdu_sessions() == 0) { if (sd.get()->get_number_pdu_sessions() == 0) {
Logger::smf_app().debug( Logger::smf_app().debug(
"Unsubscribe from Session Management Subscription data changes notification from UDM"); "Unsubscribe from Session Management Subscription data changes notification from UDM");
...@@ -2120,12 +2142,12 @@ void smf_context::handle_pdu_session_update_sm_context_request( ...@@ -2120,12 +2142,12 @@ void smf_context::handle_pdu_session_update_sm_context_request(
return; return;
} }
/* //SMF send response to AMF /* //SMF send response to AMF
oai::smf_server::model::SmContextCreatedData smContextCreatedData; //Verify, do we need this? oai::smf_server::model::SmContextCreatedData smContextCreatedData; //Verify, do we need this?
smf_n11_inst->send_pdu_session_create_sm_context_response( smf_n11_inst->send_pdu_session_create_sm_context_response(
smreq->http_response, smContextCreatedData, smreq->http_response, smContextCreatedData,
Pistache::Http::Code::Ok); Pistache::Http::Code::Ok);
*/ */
//don't need to create a procedure to update UPF //don't need to create a procedure to update UPF
//Send ITTI to N11 to send PDUSession_UpdateSMContext Response to AMF //Send ITTI to N11 to send PDUSession_UpdateSMContext Response to AMF
//No need to create N1/N2 Container //No need to create N1/N2 Container
...@@ -2139,7 +2161,6 @@ void smf_context::handle_pdu_session_update_sm_context_request( ...@@ -2139,7 +2161,6 @@ void smf_context::handle_pdu_session_update_sm_context_request(
sm_context_resp_pending->get_msg_name()); sm_context_resp_pending->get_msg_name());
} }
} }
break; break;
...@@ -2262,88 +2283,7 @@ void smf_context::handle_pdu_session_update_sm_context_request( ...@@ -2262,88 +2283,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
} }
} }
/* else {
//TODO: send PDUSession_UpdateSMContextResponse
//Prepare response to send to AMF (N1N2MessageTransfer or PDUSession_UpdateSMContextResponse)
nlohmann::json sm_context_updated_data = { };
sm_context_updated_data["n1MessageContainer"]["n1MessageClass"] =
N1N2_MESSAGE_CLASS;
sm_context_updated_data["n1MessageContainer"]["n1MessageContent"]["contentId"] =
N1_SM_CONTENT_ID;
sm_context_updated_data["n2InfoContainer"]["n2InformationClass"] =
N1N2_MESSAGE_CLASS;
sm_context_updated_data["n2InfoContainer"]["smInfo"]["PduSessionId"] =
n11_sm_context_resp->res.get_pdu_session_id();
sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] =
N2_SM_CONTENT_ID;
switch (procedure_type) {
//PDU Session Modification UE-initiated (Step 1)
case session_management_procedures_type_e::PDU_SESSION_MODIFICATION_UE_INITIATED_STEP1: {
//N1 SM: PDU Session Modification Command
//N2 SM: PDU Session Resource Modify Request Transfer IE
//N1 SM
smf_n1_n2_inst.create_n1_sm_container(
n11_sm_context_resp->res, PDU_SESSION_MODIFICATION_COMMAND,
n1_sm_msg, cause_value_5gsm_e::CAUSE_0_UNKNOWN); //TODO: need cause?
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
n11_sm_context_resp->res.set_n1_sm_message(n1_sm_msg_hex);
//N2 SM Information
smf_n1_n2_inst.create_n2_sm_information(
n11_sm_context_resp->res, 1, n2_sm_info_type_e::PDU_RES_MOD_REQ,
n2_sm_info);
smf_app_inst->convert_string_2_hex(n2_sm_info, n2_sm_info_hex);
n11_sm_context_resp->res.set_n2_sm_information(n2_sm_info_hex);
//fill the content of SmContextUpdatedData
n11_sm_context_resp->res.sm_context_updated_data =
sm_context_updated_data;
n11_sm_context_resp->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
"PDU_RES_MOD_REQ"; //NGAP message
}
break;
//PDU Session Release UE-initiated (Step 2)
case session_management_procedures_type_e::PDU_SESSION_RELEASE_UE_REQUESTED_STEP2: {
//No need to create N1/N2 Container
Logger::smf_app().info("PDU Session Release UE-initiated (Step 2)");
//TODO:
}
break;
//PDU Session Release UE-initiated (Step 3)
case session_management_procedures_type_e::PDU_SESSION_RELEASE_UE_REQUESTED_STEP3: {
//No need to create N1/N2 Container
Logger::smf_app().info("PDU Session Release UE-initiated (Step 3)");
//TODO: To be completed
}
break;
default: {
Logger::smf_app().info("Unknown session procedure type %d",
procedure_type);
}
}
//send ITTI message to N11 interface to trigger SessionUpdateSMContextResponse towards AMFs
Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name());
sm_context_resp_pending->session_procedure_type = procedure_type;
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 //TODO, Step 6
/* If the PDU Session establishment is not successful, the SMF informs the AMF by invoking Nsmf_PDUSession_SMContextStatusNotify (Release). The SMF also releases any N4 /* If the PDU Session establishment is not successful, the SMF informs the AMF by invoking Nsmf_PDUSession_SMContextStatusNotify (Release). The SMF also releases any N4
session(s) created, any PDU Session address if allocated (e.g. IP address) and releases the association with PCF, session(s) created, any PDU Session address if allocated (e.g. IP address) and releases the association with PCF,
......
...@@ -1123,13 +1123,13 @@ void session_update_sm_context_procedure::handle_itti_msg( ...@@ -1123,13 +1123,13 @@ void session_update_sm_context_procedure::handle_itti_msg(
//N1 SM //N1 SM
smf_n1_n2_inst.create_n1_sm_container( smf_n1_n2_inst.create_n1_sm_container(
n11_triggered_pending->res, PDU_SESSION_MODIFICATION_COMMAND, n11_triggered_pending->res, PDU_SESSION_MODIFICATION_REQUEST,
n1_sm_msg, cause_value_5gsm_e::CAUSE_0_UNKNOWN); n1_sm_msg, cause_value_5gsm_e::CAUSE_0_UNKNOWN);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex); smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
n11_triggered_pending->res.set_n1_sm_message(n1_sm_msg_hex); n11_triggered_pending->res.set_n1_sm_message(n1_sm_msg_hex);
//N2 SM Information //N2 SM Information
smf_n1_n2_inst.create_n2_sm_information( smf_n1_n2_inst.create_n2_sm_information(
n11_triggered_pending->res, 1, n2_sm_info_type_e::PDU_RES_REL_RSP, n11_triggered_pending->res, 1, n2_sm_info_type_e::PDU_RES_MOD_REQ,
n2_sm_info); n2_sm_info);
smf_app_inst->convert_string_2_hex(n2_sm_info, n2_sm_info_hex); smf_app_inst->convert_string_2_hex(n2_sm_info, n2_sm_info_hex);
n11_triggered_pending->res.set_n2_sm_information(n2_sm_info_hex); n11_triggered_pending->res.set_n2_sm_information(n2_sm_info_hex);
...@@ -1138,7 +1138,7 @@ void session_update_sm_context_procedure::handle_itti_msg( ...@@ -1138,7 +1138,7 @@ void session_update_sm_context_procedure::handle_itti_msg(
n11_triggered_pending->res.sm_context_updated_data = n11_triggered_pending->res.sm_context_updated_data =
sm_context_updated_data; sm_context_updated_data;
n11_triggered_pending->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] = n11_triggered_pending->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
"PDU_RES_REL_RSP"; //NGAP message "PDU_RES_MOD_REQ"; //NGAP message
} }
break; break;
......
...@@ -383,6 +383,142 @@ void send_pdu_session_update_sm_context_establishment( ...@@ -383,6 +383,142 @@ void send_pdu_session_update_sm_context_establishment(
free(buffer); free(buffer);
} }
//------------------------------------------------------------------------------
void send_pdu_session_modification_request_step1(std::string smf_ip_address) {
std::cout << "[AMF N11] PDU Session Modification Request (SM Context Update, Step 1)"
<< std::endl;
nlohmann::json pdu_session_modification_request;
//encode PDU Session Modification Request
/*
0000 2e 01 01 d1 00 00 00 00 00 00 00 00 00 00 00 00
*/
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, 0xc9, size); //MessageType - PDU Session Modification Request
ENCODE_U8(buffer + size, 0x28, size); //_5GSMCapability
ENCODE_U8(buffer + size, 0x01, size); //_5GSMCapability
ENCODE_U8(buffer + size, 0x00, size); //_5GSMCapability
ENCODE_U8(buffer + size, 0x59, size); //_5GSMCause
ENCODE_U8(buffer + size, 0x00, size); //_5GSMCause
ENCODE_U8(buffer + size, 0x7a, size); //_5GSMCause
ENCODE_U8(buffer + size, 0x00, size); //_5GSMCause
ENCODE_U8(buffer + size, 0x09, size); //_5GSMCause
ENCODE_U8(buffer + size, 0x01, size); //_5GSMCause
ENCODE_U8(buffer + size, 0x00, size); //_5GSMCause
ENCODE_U8(buffer + size, 0x06, size); //_5GSMCause
ENCODE_U8(buffer + size, 0x31, size); //_5GSMCause
ENCODE_U8(buffer + size, 0x31, size); //_5GSMCause
ENCODE_U8(buffer + size, 0x01, size); //_5GSMCause
ENCODE_U8(buffer + size, 0x01, size); //_5GSMCause
ENCODE_U8(buffer + size, 0x01, size); //_5GSMCause
ENCODE_U8(buffer + size, 0x3c, size); //_5GSMCause
// ENCODE_U8(buffer + size, 0x00, size); //MaximumNumberOfSupportedPacketFilters
// ENCODE_U8(buffer + size, 0x01, size); //MaximumNumberOfSupportedPacketFilters
/*
ExtendedProtocolDiscriminator extendedprotocoldiscriminator;
PDUSessionIdentity pdusessionidentity;
ProcedureTransactionIdentity proceduretransactionidentity;
MessageType messagetype;
uint16_t presence;
_5GSMCapability _5gsmcapability;
_5GSMCause _5gsmcause;
MaximumNumberOfSupportedPacketFilters maximumnumberofsupportedpacketfilters;
AlwaysonPDUSessionRequested alwaysonpdusessionrequested;
IntergrityProtectionMaximumDataRate intergrityprotectionmaximumdatarate;
QOSRules qosrules;
QOSFlowDescriptions qosflowdescriptions;
MappedEPSBearerContexts mappedepsbearercontexts;
ExtendedProtocolConfigurationOptions extendedprotocolconfigurationoptions;
*/
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_request["pduSessionId"] = 1;
pdu_session_modification_request["n1SmMsg"]["contentId"] = "n1SmMsg"; // NAS
std::string body;
std::string boundary = "----Boundary";
std::string json_part = pdu_session_modification_request.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 Request, 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) {
...@@ -879,16 +1015,22 @@ int main(int argc, char *argv[]) { ...@@ -879,16 +1015,22 @@ int main(int argc, char *argv[]) {
usleep(100000); usleep(100000);
send_pdu_session_update_sm_context_establishment(smf_ip_address); send_pdu_session_update_sm_context_establishment(smf_ip_address);
usleep(200000); usleep(200000);
//UE-initiated Service Request /* //UE-initiated Service Request
send_pdu_session_update_sm_context_ue_service_request(smf_ip_address); send_pdu_session_update_sm_context_ue_service_request(smf_ip_address);
usleep(200000); usleep(200000);
send_pdu_session_update_sm_context_ue_service_request_step2(smf_ip_address); send_pdu_session_update_sm_context_ue_service_request_step2(smf_ip_address);
usleep(200000);
*/
//PDU Session Modification
send_pdu_session_modification_request_step1(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);
send_pdu_session_release_resource_release_ack(smf_ip_address); send_pdu_session_release_resource_release_ack(smf_ip_address);
usleep(200000); usleep(200000);
send_pdu_session_release_complete(smf_ip_address); send_pdu_session_release_complete(smf_ip_address);
usleep(200000);
*/
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