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 @@
#include "TLVDecoder.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_qosrulesie = NULL;
uint8_t len_pos_qos_rule = 0;
uint8_t bitstream = 0;
uint32_t encoded = 0;
int encode_result = 0;
int i = 0,j = 0;
int i = 0, j = 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;
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;
/*
*(buffer + encoded) = qosrules.lengthofqosrulesie/(1<<8);
encoded++;
*(buffer + encoded) = qosrules.lengthofqosrulesie%(1<<8);
encoded++;
*/
for(i = 0; i < qosrules.lengthofqosrulesie; i++)
{
ENCODE_U8(buffer + encoded, qosrules.qosrulesie[i].qosruleidentifer, encoded);
for (i = 0; i < qosrules.lengthofqosrulesie; i++) {
ENCODE_U8(buffer + encoded, qosrules.qosrulesie[i].qosruleidentifer,
encoded);
len_qosrule = buffer + encoded;
encoded++;
encoded++;
len_pos_qos_rule = encoded;
bitstream = (uint8_t)(qosrules.qosrulesie[i].ruleoperationcode << 5);
bitstream |= (uint8_t)(qosrules.qosrulesie[i].dqrbit << 4);
bitstream |= (uint8_t)qosrules.qosrulesie[i].numberofpacketfilters;
ENCODE_U8(buffer+encoded,bitstream,encoded);
if((bitstream >> 5) == MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS)
{
for(j = 0; j < (bitstream & 0x0f); j++)
{
ENCODE_U8(buffer + encoded, (uint8_t)qosrules.qosrulesie[i].packetfilterlist.modifyanddelete[j].packetfilteridentifier, encoded);
bitstream = (uint8_t) (qosrules.qosrulesie[i].ruleoperationcode << 5);
bitstream |= (uint8_t) (qosrules.qosrulesie[i].dqrbit << 4);
bitstream |= (uint8_t) qosrules.qosrulesie[i].numberofpacketfilters;
ENCODE_U8(buffer + encoded, bitstream, encoded);
if ((bitstream >> 5) == MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS) {
for (j = 0; j < (bitstream & 0x0f); j++) {
ENCODE_U8(
buffer + encoded,
(uint8_t )qosrules.qosrulesie[i].packetfilterlist.modifyanddelete[j]
.packetfilteridentifier,
encoded);
}
ENCODE_U8(buffer + encoded, qosrules.qosrulesie[i].qosruleprecedence, encoded);
ENCODE_U8(buffer + encoded, (uint8_t)((qosrules.qosrulesie[i].segregation<<6) | (qosrules.qosrulesie[i].qosflowidentifer & 0x3f)), 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);
ENCODE_U8(buffer + encoded, qosrules.qosrulesie[i].qosruleprecedence,
encoded);
ENCODE_U8(
buffer + encoded,
(uint8_t )((qosrules.qosrulesie[i].segregation << 6)
| (qosrules.qosrulesie[i].qosflowidentifer & 0x3f)),
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;
encoded++;
ENCODE_U8(buffer + encoded, qosrules.qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace[j].packetfiltercontents.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)
ENCODE_U8(
buffer + encoded,
qosrules.qosrulesie[i].packetfilterlist
.create_modifyandadd_modifyandreplace[j].packetfiltercontents
.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;
else
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, (uint8_t)((qosrules.qosrulesie[i].segregation<<6) | (qosrules.qosrulesie[i].qosflowidentifer & 0x3f)), encoded);
ENCODE_U8(buffer + encoded, qosrules.qosrulesie[i].qosruleprecedence,
encoded);
ENCODE_U8(
buffer + encoded,
(uint8_t )((qosrules.qosrulesie[i].segregation << 6)
| (qosrules.qosrulesie[i].qosflowidentifer & 0x3f)),
encoded);
}
//len of qos rule
......@@ -95,118 +118,129 @@ int encode_qos_rules ( QOSRules qosrules, uint8_t iei, uint8_t * buffer, uint32_
return encoded;
}
int decode_qos_rules ( QOSRules * qosrules, uint8_t iei, uint8_t * buffer, uint32_t len )
{
int decoded=0;
uint16_t ielen=0;
int decode_qos_rules(QOSRules *qosrules, uint8_t iei, uint8_t *buffer,
uint32_t len) {
int decoded = 0;
uint16_t ielen = 0;
int decode_result = 0;
uint16_t numberrules = 0;
// uint16_t lenqosrule = 0;
uint8_t bitstream = 0;
int i=0,j=0;
int i = 0, j = 0;
if (iei > 0)
{
CHECK_IEI_DECODER (iei, *buffer);
if (iei > 0) {
CHECK_IEI_DECODER(iei, *buffer);
decoded++;
}
numberrules = *(buffer + decoded);
decoded++;
numberrules = ( numberrules << 8)+*(buffer + decoded);
decoded++;
for(i=0;i<numberrules;i++)
{
ielen = *(buffer + ielen + 1) + 1;
}
CHECK_LENGTH_DECODER (len - decoded, ielen);
qosrules->lengthofqosrulesie = numberrules;
qosrules->qosrulesie = (QOSRulesIE *)calloc(numberrules,sizeof(QOSRulesIE));
for(i=0;i<numberrules;i++)
{
DECODE_U8(buffer+decoded,qosrules->qosrulesie[i].qosruleidentifer,decoded);
decoded++;
decoded++;
/*lenqosrule = *(buffer + decoded);
decoded++;
lenqosrule = (lenqosrule << 8)+*(buffer + decoded);
decoded++;
lenmoment = encoded;
*/
DECODE_U8(buffer+decoded,bitstream,decoded);
qosrules->qosrulesie[i].ruleoperationcode = (bitstream>>5);
qosrules->qosrulesie[i].dqrbit = (bitstream>>4)&0x01;
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_U16(buffer + decoded, qosrules->lengthofqosrulesie, decoded);
CHECK_LENGTH_DECODER(len - decoded, qosrules->lengthofqosrulesie);
qosrules->qosrulesie = (QOSRulesIE*) calloc(1, sizeof(QOSRulesIE));
i = 0;
//for(i=0;i<numberrules;i++)
while (decoded < qosrules->lengthofqosrulesie) {
DECODE_U8(buffer + decoded, qosrules->qosrulesie[i].qosruleidentifer,
decoded);
// decoded++;
// decoded++;
DECODE_U16(buffer + decoded, qosrules->qosrulesie[i].LengthofQoSrule, decoded);
DECODE_U8(buffer + decoded, bitstream, decoded);
qosrules->qosrulesie[i].ruleoperationcode = (bitstream >> 5);
qosrules->qosrulesie[i].dqrbit = (bitstream >> 4) & 0x01;
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;
DECODE_U8(buffer+decoded,bitstream,decoded);
qosrules->qosrulesie[i].segregation = (bitstream>>6)&0x01;
qosrules->qosrulesie[i].qosflowidentifer = bitstream&0x3f;
}
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].packetfilterlist.create_modifyandadd_modifyandreplace = (Create_ModifyAndAdd_ModifyAndReplace *)calloc(qosrules->qosrulesie[i].numberofpacketfilters,sizeof(Create_ModifyAndAdd_ModifyAndReplace));
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);
DECODE_U8(buffer + decoded, bitstream, decoded); //QoS flow identifier (QFI)
qosrules->qosrulesie[i].segregation = (bitstream >> 6) & 0x01;
qosrules->qosrulesie[i].qosflowidentifer = bitstream & 0x3f;
} 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].packetfilterlist
.create_modifyandadd_modifyandreplace =
(Create_ModifyAndAdd_ModifyAndReplace*) calloc(
qosrules->qosrulesie[i].numberofpacketfilters,
sizeof(Create_ModifyAndAdd_ModifyAndReplace));
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++;
DECODE_U8(buffer+decoded,bitstream,decoded);
qosrules->qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace[j].packetfiltercontents.component_type = bitstream;
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)
DECODE_U8(buffer + decoded, bitstream, decoded);
qosrules->qosrulesie[i].packetfilterlist
.create_modifyandadd_modifyandreplace[j].packetfiltercontents
.component_type = bitstream;
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;
else
decoded += decode_result;
}
}
DECODE_U8(buffer+decoded,bitstream,decoded);
DECODE_U8(buffer + decoded, bitstream, decoded);
qosrules->qosrulesie[i].qosruleprecedence = bitstream;
DECODE_U8(buffer+decoded,bitstream,decoded);
qosrules->qosrulesie[i].segregation = (bitstream>>6)&0x01;
qosrules->qosrulesie[i].qosflowidentifer = bitstream&0x3f;
DECODE_U8(buffer + decoded, bitstream, decoded);
qosrules->qosrulesie[i].segregation = (bitstream >> 6) & 0x01;
qosrules->qosrulesie[i].qosflowidentifer = bitstream & 0x3f;
}
i++;
}
return decoded;
}
void free_decode_qos_rules(QOSRules * qosrules)
{
void free_decode_qos_rules(QOSRules *qosrules) {
int i;
for(i = 0; i < qosrules->lengthofqosrulesie; i++)
{
if(qosrules->qosrulesie[i].ruleoperationcode == MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS)
{
for (i = 0; i < qosrules->lengthofqosrulesie; i++) {
if (qosrules->qosrulesie[i].ruleoperationcode
== MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS) {
free(qosrules->qosrulesie[i].packetfilterlist.modifyanddelete);
qosrules->qosrulesie[i].packetfilterlist.modifyanddelete = NULL;
}
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))
{
free(qosrules->qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace);
qosrules->qosrulesie[i].packetfilterlist.create_modifyandadd_modifyandreplace = NULL;
} 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)) {
free(
qosrules->qosrulesie[i].packetfilterlist
.create_modifyandadd_modifyandreplace);
qosrules->qosrulesie[i].packetfilterlist
.create_modifyandadd_modifyandreplace = NULL;
}
}
free(qosrules->qosrulesie);
......
......@@ -1341,9 +1341,6 @@ void smf_context::handle_pdu_session_update_sm_context_request(
sm_context_resp_pending->session_procedure_type =
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)
if (sp.get()->get_pdu_session_status()
== pdu_session_status_e::PDU_SESSION_INACTIVE_PENDING) {
......@@ -1391,8 +1388,9 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//TODO: IntergrityProtectionMaximumDataRate
//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;
QOSRulesIE *qos_rules_ie = (QOSRulesIE*) calloc(1, sizeof(QOSRulesIE));
qos_rules_ie = decoded_nas_msg.plain.sm.pdu_session_modification_request
.qosrules.qosrulesie;
......@@ -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 };
QOSRulesIE qos_rule = { };
pfcp::qfi_t qfi = { };
smf_qos_flow qos_flow = { };
length_of_rule = qos_rules_ie[i].LengthofQoSrule;
//If UE requested a new GBR flow
if ((qos_rules_ie[i].ruleoperationcode == CREATE_NEW_QOS_RULE)
and (qos_rules_ie[i].segregation == SEGREGATION_REQUESTED)) {
......@@ -1498,17 +1501,33 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//Add new 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 {
qfi.qfi = qos_rules_ie[i].qosflowidentifer;
sp.get()->get_qos_flow(qfi, qos_flow);
qos_flow.update_qos_rule(qos_rules_ie[i]);
//update 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: ExtendedProtocolConfigurationOptions
......@@ -1544,16 +1563,18 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//Fill the json part
//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;
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
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;
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
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
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
sp.get()->set_pdu_session_status(
......@@ -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",
sm_context_resp_pending->get_msg_name());
}
free_wrapper((void**) &qos_rules_ie);
free_wrapper((void**) &qos_flow_description);
}
break;
......@@ -1602,16 +1626,15 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//stop T3591
itti_inst->timer_remove(sp.get()->timer_T3591);
/* //Send PDUSession_UpdateSMContext Response to AMF
//No need to create N1/N2 Container
Logger::smf_app().info(
"PDU Session Modification UE-initiated (Step 3)");
smContextUpdatedData = { };
smf_n11_inst->send_pdu_session_update_sm_context_response(
n11_sm_context_resp->http_response, smContextUpdatedData,
Pistache::Http::Code::No_Content);
*/
/* //Send PDUSession_UpdateSMContext Response to AMF
//No need to create N1/N2 Container
Logger::smf_app().info(
"PDU Session Modification UE-initiated (Step 3)");
smContextUpdatedData = { };
smf_n11_inst->send_pdu_session_update_sm_context_response(
n11_sm_context_resp->http_response, smContextUpdatedData,
Pistache::Http::Code::No_Content);
*/
//don't need to create a procedure to update UPF
//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(
//stop T3591
itti_inst->timer_remove(sp.get()->timer_T3591);
/* //Send PDUSession_UpdateSMContext Response to AMF
//No need to create N1/N2 Container
Logger::smf_app().info(
"PDU Session Modification UE-initiated (Step 3)");
smContextUpdatedData = { };
smf_n11_inst->send_pdu_session_update_sm_context_response(
n11_sm_context_resp->http_response, smContextUpdatedData,
Pistache::Http::Code::No_Content);
*/
/* //Send PDUSession_UpdateSMContext Response to AMF
//No need to create N1/N2 Container
Logger::smf_app().info(
"PDU Session Modification UE-initiated (Step 3)");
smContextUpdatedData = { };
smf_n11_inst->send_pdu_session_update_sm_context_response(
n11_sm_context_resp->http_response, smContextUpdatedData,
Pistache::Http::Code::No_Content);
*/
//don't need to create a procedure to update UPF
//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(
//Release the resources related to this PDU Session (in Procedure)
//find DNN context
/* std::shared_ptr<dnn_context> sd = { };
if ((!find_dnn_context(sm_context_req_msg.get_snssai(),
sm_context_req_msg.get_dnn(), sd))
or (nullptr == sd.get())) {
Logger::smf_app().warn(
"Could not find the context for this PDU session");
//create PDU Session Release Reject and send to UE
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]);
smContextUpdateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData);
smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg, PDU_SESSION_RELEASE_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_111_PROTOCOL_ERROR_UNSPECIFIED);
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::Not_Found, n1_sm_msg_hex);
return;
}
//find PDU Session
std::shared_ptr<smf_pdu_session> sp;
if ((!sd.get()->find_pdu_session(
sm_context_req_msg.get_pdu_session_id(), sp))
or (nullptr == sp.get())) {
Logger::smf_app().warn(
"Could not find the context for this PDU session");
//create PDU Session Release Reject and send to UE
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]);
smContextUpdateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData);
smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg, PDU_SESSION_RELEASE_REJECT, n1_sm_msg,
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_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Not_Found, n1_sm_msg_hex);
return;
}
*/
/* std::shared_ptr<dnn_context> sd = { };
if ((!find_dnn_context(sm_context_req_msg.get_snssai(),
sm_context_req_msg.get_dnn(), sd))
or (nullptr == sd.get())) {
Logger::smf_app().warn(
"Could not find the context for this PDU session");
//create PDU Session Release Reject and send to UE
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]);
smContextUpdateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData);
smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg, PDU_SESSION_RELEASE_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_111_PROTOCOL_ERROR_UNSPECIFIED);
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::Not_Found, n1_sm_msg_hex);
return;
}
//find PDU Session
std::shared_ptr<smf_pdu_session> sp;
if ((!sd.get()->find_pdu_session(
sm_context_req_msg.get_pdu_session_id(), sp))
or (nullptr == sp.get())) {
Logger::smf_app().warn(
"Could not find the context for this PDU session");
//create PDU Session Release Reject and send to UE
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]);
smContextUpdateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData);
smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg, PDU_SESSION_RELEASE_REJECT, n1_sm_msg,
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_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Not_Found, n1_sm_msg_hex);
return;
}
*/
//get the associated QoS flows: to be used for PFCP Session Modification procedure
std::vector<smf_qos_flow> qos_flows;
sp.get()->get_qos_flows(qos_flows);
......@@ -1846,11 +1869,11 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//Stop timer T3592
itti_inst->timer_remove(sp.get()->timer_T3592);
/* //send response to AMF
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdatedData,
Pistache::Http::Code::No_Content);
*/
/* //send response to AMF
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdatedData,
Pistache::Http::Code::No_Content);
*/
//don't need to create a procedure to update UPF
//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(
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: 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
//find dnn context
/* std::shared_ptr<dnn_context> sd = { };
bool find_dnn = find_dnn_context(sm_context_req_msg.get_snssai(),
sm_context_req_msg.get_dnn(), sd);
//At this step, this context should be existed
if (nullptr == sd.get()) {
Logger::smf_app().debug(
"DNN context (dnn_in_use %s) is not existed yet!",
sm_context_req_msg.get_dnn().c_str());
//TODO:
}
*/
/* std::shared_ptr<dnn_context> sd = { };
bool find_dnn = find_dnn_context(sm_context_req_msg.get_snssai(),
sm_context_req_msg.get_dnn(), sd);
//At this step, this context should be existed
if (nullptr == sd.get()) {
Logger::smf_app().debug(
"DNN context (dnn_in_use %s) is not existed yet!",
sm_context_req_msg.get_dnn().c_str());
//TODO:
}
*/
if (sd.get()->get_number_pdu_sessions() == 0) {
Logger::smf_app().debug(
"Unsubscribe from Session Management Subscription data changes notification from UDM");
......@@ -2120,12 +2142,12 @@ void smf_context::handle_pdu_session_update_sm_context_request(
return;
}
/* //SMF send response to AMF
oai::smf_server::model::SmContextCreatedData smContextCreatedData; //Verify, do we need this?
smf_n11_inst->send_pdu_session_create_sm_context_response(
smreq->http_response, smContextCreatedData,
Pistache::Http::Code::Ok);
*/
/* //SMF send response to AMF
oai::smf_server::model::SmContextCreatedData smContextCreatedData; //Verify, do we need this?
smf_n11_inst->send_pdu_session_create_sm_context_response(
smreq->http_response, smContextCreatedData,
Pistache::Http::Code::Ok);
*/
//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
......@@ -2139,7 +2161,6 @@ void smf_context::handle_pdu_session_update_sm_context_request(
sm_context_resp_pending->get_msg_name());
}
}
break;
......@@ -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
/* 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,
......
......@@ -1123,13 +1123,13 @@ void session_update_sm_context_procedure::handle_itti_msg(
//N1 SM
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);
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);
//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);
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);
......@@ -1138,7 +1138,7 @@ void session_update_sm_context_procedure::handle_itti_msg(
n11_triggered_pending->res.sm_context_updated_data =
sm_context_updated_data;
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;
......
......@@ -383,6 +383,142 @@ void send_pdu_session_update_sm_context_establishment(
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) {
......@@ -879,16 +1015,22 @@ int main(int argc, char *argv[]) {
usleep(100000);
send_pdu_session_update_sm_context_establishment(smf_ip_address);
usleep(200000);
//UE-initiated Service Request
/* //UE-initiated Service Request
send_pdu_session_update_sm_context_ue_service_request(smf_ip_address);
usleep(200000);
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
send_pdu_session_release_request(smf_ip_address);
/* send_pdu_session_release_request(smf_ip_address);
usleep(200000);
send_pdu_session_release_resource_release_ack(smf_ip_address);
usleep(200000);
send_pdu_session_release_complete(smf_ip_address);
usleep(200000);
*/
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