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

Merge branch 'pdu_session_modification_v1.0' into 'develop'

Pdu session modification (UE-initiated, first step)

See merge request oai/oai-cn5g-smf!8
parents f6e168f8 391dfe65
......@@ -55,20 +55,6 @@ cd /oai-cn5g-smf/build/scripts
cd /oai-cn5g-smf/build/scripts
./smf_conf.sh
## launch SMF
sudo smf -c /usr/local/etc/oai/smf.conf -o
## Build UPF (SPGWU) and Launch UPF (SPGWU)
git clone https://github.com/OPENAIRINTERFACE/openair-cn-cups/
cd /openair-cn-cups/build/scripts
./build_spgwu -I -f
./build_spgwu -c -V -b Debug -j
#configure SPGWU using an example configure file (spgw_u.conf)
cd /oai-cn5g-smf/src/test/upf/
./spgwu_conf.sh
sudo spgwu -c /usr/local/etc/oai/spgw_u.conf -o
## Build and launch UDM
cd /oai-cn5g-smf/src/test/udm
mkdir build
......@@ -85,6 +71,22 @@ cmake ..
make
sudo ./amf-server -i 172.16.1.102
## launch SMF
sudo smf -c /usr/local/etc/oai/smf.conf -o
## Build UPF (SPGWU) and Launch UPF (SPGWU)
git clone https://github.com/OPENAIRINTERFACE/openair-cn-cups/
cd /openair-cn-cups/build/scripts
./build_spgwu -I -f
./build_spgwu -c -V -b Debug -j
#configure SPGWU using an example configure file (spgw_u.conf)
cd /oai-cn5g-smf/src/test/upf/
./spgwu_conf.sh
sudo spgwu -c /usr/local/etc/oai/spgw_u.conf -o
## Build and launch AMF client
cd /oai-cn5g-smf/src/test/amf_client
mkdir build
......
......@@ -131,7 +131,7 @@ void IndividualSMContextApi::release_sm_context_handler(
//return;
}
free_wrapper((void **) &data);
free_wrapper((void**) &data);
uint8_t size = g_parts.size();
Logger::smf_api_server().debug("Number of g_parts %d", g_parts.size());
......@@ -204,6 +204,7 @@ void IndividualSMContextApi::update_sm_context_handler(
const Pistache::Rest::Request &request,
Pistache::Http::ResponseWriter response) {
Logger::smf_api_server().debug("");
Logger::smf_api_server().info(
"Received a SM context update request from AMF");
Logger::smf_api_server().debug("Request body: %s\n", request.body().c_str());
......@@ -247,16 +248,19 @@ void IndividualSMContextApi::update_sm_context_handler(
//return;
}
free_wrapper((void **) &data);
free_wrapper((void**) &data);
uint8_t size = g_parts.size();
Logger::smf_api_server().debug("Number of g_parts %d", g_parts.size());
part p0 = g_parts.front();
g_parts.pop_front();
Logger::smf_api_server().debug("Request body, part 1: %s", p0.body.c_str());
part p0 = { };
part p1 = { };
if (size > 0) {
p0 = g_parts.front();
g_parts.pop_front();
Logger::smf_api_server().debug("Request body, part 1: %s", p0.body.c_str());
}
if (size > 1) {
p1 = g_parts.front();
g_parts.pop_front();
......@@ -269,7 +273,12 @@ void IndividualSMContextApi::update_sm_context_handler(
// Getting the body param
SmContextUpdateData smContextUpdateData = { };
try {
nlohmann::json::parse(p0.body.c_str()).get_to(smContextUpdateData);
if (size > 0) {
nlohmann::json::parse(p0.body.c_str()).get_to(smContextUpdateData);
} else {
nlohmann::json::parse(request.body().c_str()).get_to(smContextUpdateData);
}
smContextUpdateMessage.setJsonData(smContextUpdateData);
if (size > 1) {
......
......@@ -31,14 +31,14 @@ void IndividualPDUSessionHSMFApiImpl::release_pdu_session(
const std::string &pduSessionRef, const ReleaseData &releaseData,
Pistache::Http::ResponseWriter &response) {
Logger::smf_api_server().info("release_pdu_session...");
response.send(Pistache::Http::Code::Ok,
response.send(Pistache::Http::Code::Not_Implemented,
"Release_pdu_session API has not been implemented yet!\n");
}
void IndividualPDUSessionHSMFApiImpl::update_pdu_session(
const std::string &pduSessionRef, const HsmfUpdateData &hsmfUpdateData,
Pistache::Http::ResponseWriter &response) {
Logger::smf_api_server().info("update_pdu_session...");
response.send(Pistache::Http::Code::Ok,
response.send(Pistache::Http::Code::Not_Implemented,
"Update_pdu_session API has not been implemented yet!\n");
}
......
......@@ -90,7 +90,7 @@ void IndividualSMContextApiImpl::retrieve_sm_context(
const SmContextRetrieveData &smContextRetrieveData,
Pistache::Http::ResponseWriter &response) {
Logger::smf_api_server().info("retrieve_sm_context...");
response.send(Pistache::Http::Code::Ok,
response.send(Pistache::Http::Code::Not_Implemented,
"Retrieve_sm_context API has not been implemented yet!\n");
}
......@@ -130,13 +130,13 @@ void IndividualSMContextApiImpl::update_sm_context(
/* UE-initiated Service Request Operation, section 4.2.3.2@3GPP TS 23.502 */
//Step 4: PDU Session IDs, Operation Type, UE location Info, Access Type, RAT Type, UE presence in LADN service area, Indication of Access Type can be changed
//PDU Session IDs
//UpCnxState, for activation of user plane (see 5.2.2.3.2.2@3GPP TS 29.502)
//UpCnxState, for activation of user plane (see 5.2.2.3.2.2@3GPP TS 29.502, step 1)
if (smContextUpdateData.upCnxStateIsSet())
sm_context_req_msg.set_upCnx_state(smContextUpdateData.getUpCnxState());
//Access Type
//Access Type (step 1 and 2)
if (smContextUpdateData.anTypeIsSet())
sm_context_req_msg.set_an_type(smContextUpdateData.getAnType());
//RAT Type
//RAT Type (step 1 and 2)
if (smContextUpdateData.ratTypeIsSet())
sm_context_req_msg.set_rat_type(smContextUpdateData.getRatType());
//TODO:
......@@ -150,6 +150,12 @@ void IndividualSMContextApiImpl::update_sm_context(
//TODO: Existing PDU session, step 3, SUPI, DNN, S-NSSAIs, SM Context ID, AMF ID, Request Type, N1 SM Container (PDU Session Establishment Request), User location, Access Type, RAT Type, PEI
//step 15. (SM Context ID -> SCID, N2 SM, Request Type)(Initial Request)
//TODO: verify why Request Type is not define in smContextUpdateData
/* AMF-initiated with a release indication to request the release of the PDU Session (step 3.d, section 4.3.4.2@3GPP TS 23.502)*/
if (smContextUpdateData.releaseIsSet()) {
sm_context_req_msg.set_release(smContextUpdateData.isRelease());
}
/* PDU Session Modification (SM Context ID -> SCID, N1/N2), section 4.3.3.2@3GPP TS 23.502: */
//step 1.a,UE-initiated: SM Context ID + N1 (PDU Session Modification Request)
//step 1.e (AN initiated modification): SM Context ID, N2 SM information (QFI, User location Information and an indication that the QoS Flow is released)
......
......@@ -31,7 +31,7 @@ void PDUSessionsCollectionApiImpl::post_pdu_sessions(
const PduSessionCreateData &pduSessionCreateData,
Pistache::Http::ResponseWriter &response) {
Logger::smf_api_server().info("post_pdu_sessions...");
response.send(Pistache::Http::Code::Ok,
response.send(Pistache::Http::Code::Not_Implemented,
"Post_pdu_sessions API has not been implemented yet!\n");
}
......
......@@ -48,7 +48,8 @@ typedef uint8_t pdu_session_id_t;
/* QFI */
// type: integer, minimum: 0, maximum: 63
#define QOS_FLOW_IDENTIFIER_FIRST (uint8_t)0
#define NO_QOS_FLOW_IDENTIFIER_ASSIGNED (uint8_t)0
#define QOS_FLOW_IDENTIFIER_FIRST (uint8_t)1
#define QOS_FLOW_IDENTIFIER_LAST (uint8_t)63
/*
......@@ -64,6 +65,12 @@ typedef uint8_t pdu_session_id_t;
} smf_qfi_t;
*/
//QoS Rule
#define NO_QOS_RULE_IDENTIFIER_ASSIGNED (uint8_t)0
#define QOS_RULE_IDENTIFIER_FIRST (uint8_t)1
#define QOS_RULE_IDENTIFIER_LAST (uint8_t)255
// Integrity protection maximum data rate
typedef struct ipmdr_s {
uint8_t ul;
......
......@@ -122,8 +122,10 @@ enum class session_management_procedures_type_e {
PDU_SESSION_RELEASE_UE_REQUESTED_STEP1 = 9,
PDU_SESSION_RELEASE_UE_REQUESTED_STEP2 = 10,
PDU_SESSION_RELEASE_UE_REQUESTED_STEP3 = 11,
PDU_SESSION_RELEASE_NETWORK_REQUESTED = 12,
PDU_SESSION_TEST = 13
PDU_SESSION_RELEASE_SMF_INITIATED = 12,
PDU_SESSION_RELEASE_AMF_INITIATED = 13,
PDU_SESSION_RELEASE_AN_INITIATED = 14,
PDU_SESSION_TEST = 15
};
static const std::vector<std::string> session_management_procedures_type_e2str =
......@@ -139,7 +141,9 @@ static const std::vector<std::string> session_management_procedures_type_e2str =
"PDU_SESSION_RELEASE_UE_REQUESTED_STEP1",
"PDU_SESSION_RELEASE_UE_REQUESTED_STEP2",
"PDU_SESSION_RELEASE_UE_REQUESTED_STEP3",
"PDU_SESSION_RELEASE_NETWORK_REQUESTED",
"PDU_SESSION_RELEASE_SMF_INITIATED",
"PDU_SESSION_RELEASE_AMF_INITIATED",
"PDU_SESSION_RELEASE_AN_INITIATED",
"PDU_SESSION_TEST"
};
......@@ -162,10 +166,10 @@ typedef struct qos_profile_s {
arp_5gc_t arp;
uint8_t priority_level;
qos_profile_type_e profile_type;
union parameter {
union {
reflective_qos_attribute_e rqa; //Reflective QoS Attribute (RQA)
qos_profile_gbr_t qos_profile_gbr; //Attributes for GBR
};
} parameter;
} qos_profile_t;
enum class multipart_related_content_part_e {
......
......@@ -109,7 +109,7 @@ extern "C" {
#define PDU_SESSION_MODIFICATION_REJECT 0b11001010
#define PDU_SESSION_MODIFICATION_COMMAND 0b11001011
#define PDU_SESSION_MODIFICATION_COMPLETE 0b11001100
#define PDU_SESSION_MODIFICATION_COMMANDREJECT 0b11001101
#define PDU_SESSION_MODIFICATION_COMMAND_REJECT 0b11001101
#define PDU_SESSION_RELEASE_REQUEST 0b11010001
#define PDU_SESSION_RELEASE_REJECT 0b11010010
......@@ -118,6 +118,7 @@ extern "C" {
#define _5GSM_STATUS 0b11010110
// 9.11.3.47 Request type
//typedef std::string request_type_t;
......@@ -226,7 +227,7 @@ enum class cause_value_5gsm_e {
CAUSE_46_OUT_OF_LAND_SERVICE_AREA = 46,
CAUSE_47_PTI_MISMATCH = 47,
CAUSE_50_PDU_SESSION_TYPE_IPV4_ONLY_ALLOWED = 50,
CAUSE_51_PDU_SESSION_TYPE_IPV6_ONLY_ALLOWED = 50,
CAUSE_51_PDU_SESSION_TYPE_IPV6_ONLY_ALLOWED = 51,
CAUSE_54_PDU_SESSION_DOES_NOT_EXIST = 54,
CAUSE_67_INSUFFICIENT_RESOURCES_FOR_SPECIFIC_SLICE_AND_DNN = 67,
CAUSE_68_NOT_SUPPORTED_SSC_MODE = 68,
......@@ -332,7 +333,6 @@ typedef struct pdu_session_type_s {
} pdu_session_type_t;
#endif
#endif
......@@ -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++)
{