diff --git a/README.md b/README.md index a6b4f0c..9db928a 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ func HandleHeartbeatRequest(sequenceNumber uint32, msg messages.HeartbeatRequest - [x] PFCP Association Setup - [x] PFCP Association Update - [x] PFCP Association Release -- [ ] PFCP Node Report +- [x] PFCP Node Report ### Session diff --git a/client/client.go b/client/client.go index 1e4ff98..f781629 100644 --- a/client/client.go +++ b/client/client.go @@ -123,3 +123,23 @@ func (pfcp *Pfcp) SendPFCPAssociationReleaseResponse(msg messages.PFCPAssociatio } return nil } + +func (pfcp *Pfcp) SendPFCPNodeReportRequest(msg messages.PFCPNodeReportRequest, sequenceNumber uint32) error { + header := headers.NewPFCPHeader(messages.PFCPNodeReportRequestMessageType, sequenceNumber) + payload := []ie.InformationElement{msg.NodeID, msg.NodeReportType} + err := pfcp.sendPfcpMessage(header, payload) + if err != nil { + return fmt.Errorf("error sending PFCP Node Report Request: %w", err) + } + return nil +} + +func (pfcp *Pfcp) SendPFCPNodeReportResponse(msg messages.PFCPNodeReportResponse, sequenceNumber uint32) error { + header := headers.NewPFCPHeader(messages.PFCPNodeReportResponseMessageType, sequenceNumber) + payload := []ie.InformationElement{msg.NodeID, msg.Cause} + err := pfcp.sendPfcpMessage(header, payload) + if err != nil { + return fmt.Errorf("error sending PFCP Node Report Response: %w", err) + } + return nil +} diff --git a/ie/cause.go b/ie/cause.go index 11f7f01..8e2687e 100644 --- a/ie/cause.go +++ b/ie/cause.go @@ -34,10 +34,6 @@ func (cause Cause) Serialize() []byte { return buf.Bytes() } -func (cause Cause) Type() uint16 { - return cause.IEtype -} - func DeserializeCause(ieType uint16, ieLength uint16, ieValue []byte) Cause { return Cause{ IEtype: ieType, diff --git a/ie/ie.go b/ie/ie.go index 1e81e4b..3599318 100644 --- a/ie/ie.go +++ b/ie/ie.go @@ -9,7 +9,6 @@ const IEHeaderLength = 4 type InformationElement interface { Serialize() []byte - Type() uint16 } func ParseInformationElements(b []byte) ([]InformationElement, error) { @@ -39,6 +38,8 @@ func ParseInformationElements(b []byte) ([]InformationElement, error) { ie = DeserializeNodeID(ieType, ieLength, ieValue) case 96: ie = DeserializeRecoveryTimeStamp(ieType, ieLength, ieValue) + case 101: + ie = DeserializeNodeReportType(ieType, ieLength, ieValue) default: err = fmt.Errorf("unknown IE type %d", ieType) } diff --git a/ie/nodeId.go b/ie/nodeId.go index ccde3dd..72c4ba3 100644 --- a/ie/nodeId.go +++ b/ie/nodeId.go @@ -87,10 +87,6 @@ func (n NodeID) Serialize() []byte { return buf.Bytes() } -func (n NodeID) Type() uint16 { - return n.IEtype -} - func DeserializeNodeID(ieType uint16, ieLength uint16, ieValue []byte) NodeID { nodeIDType := NodeIDType(ieValue[0] & 0x0F) // Ensure NodeIDType is only 4 bits nodeIDValue := ieValue[1:] diff --git a/ie/nodeReportType.go b/ie/nodeReportType.go new file mode 100644 index 0000000..c3055f9 --- /dev/null +++ b/ie/nodeReportType.go @@ -0,0 +1,75 @@ +package ie + +import ( + "bytes" + "encoding/binary" +) + +type NodeReportType struct { + IEtype uint16 + Length uint16 + GPQR bool + CKDR bool + UPRR bool + UPFR bool +} + +func NewNodeReportType(gpqr bool, ckdr bool, uprr bool, upfr bool) NodeReportType { + return NodeReportType{ + IEtype: 101, + Length: 1, + GPQR: gpqr, + CKDR: ckdr, + UPRR: uprr, + UPFR: upfr, + } +} + +func (nrt NodeReportType) Serialize() []byte { + buf := new(bytes.Buffer) + + // Octets 1 to 2: Type (60) + binary.Write(buf, binary.BigEndian, uint16(nrt.IEtype)) + + // Octets 3 to 4: Length + binary.Write(buf, binary.BigEndian, uint16(nrt.Length)) + + // Octet 5: Spare, Spare, Spare, Spare, GPQR, CKDR, UPRR, UPFR + var octet5 byte + if nrt.GPQR { + octet5 |= 1 << 3 + } + if nrt.CKDR { + octet5 |= 1 << 2 + } + if nrt.UPRR { + octet5 |= 1 << 1 + } + if nrt.UPFR { + octet5 |= 1 + } + buf.WriteByte(octet5) + + return buf.Bytes() +} + +func DeserializeNodeReportType(ieType uint16, ieLength uint16, ieValue []byte) NodeReportType { + var nrt NodeReportType + + buf := bytes.NewBuffer(ieValue) + + nrt.IEtype = ieType + nrt.Length = ieLength + + // Read the bit flags from octet 5 + var octet5 byte + if len(buf.Bytes()) > 0 { + octet5, _ = buf.ReadByte() + nrt.GPQR = octet5&0x08 != 0 + nrt.CKDR = octet5&0x04 != 0 + nrt.UPRR = octet5&0x02 != 0 + nrt.UPFR = octet5&0x01 != 0 + } + + return nrt +} diff --git a/ie/recoveryTimeStamp.go b/ie/recoveryTimeStamp.go index c04a734..d0dffc5 100644 --- a/ie/recoveryTimeStamp.go +++ b/ie/recoveryTimeStamp.go @@ -29,10 +29,6 @@ func (rt RecoveryTimeStamp) Serialize() []byte { return bytes } -func (rt RecoveryTimeStamp) Type() uint16 { - return rt.IEtype -} - func DeserializeRecoveryTimeStamp(ieType uint16, ieLength uint16, ieValue []byte) RecoveryTimeStamp { return RecoveryTimeStamp{ IEtype: ieType, diff --git a/messages/heartbeat.go b/messages/heartbeat.go index 9a03c4c..c2a9790 100644 --- a/messages/heartbeat.go +++ b/messages/heartbeat.go @@ -6,12 +6,10 @@ import ( type HeartbeatRequest struct { MessageType MessageType - SequenceNumber uint32 RecoveryTimeStamp ie.RecoveryTimeStamp } type HeartbeatResponse struct { - SequenceNumber uint32 RecoveryTimeStamp ie.RecoveryTimeStamp } diff --git a/messages/messages.go b/messages/messages.go index 1e4b9af..d511e1e 100644 --- a/messages/messages.go +++ b/messages/messages.go @@ -11,4 +11,6 @@ const ( PFCPAssociationUpdateResponseMessageType MessageType = 8 PFCPAssociationReleaseRequestMessageType MessageType = 9 PFCPAssociationReleaseResponseMessageType MessageType = 10 + PFCPNodeReportRequestMessageType MessageType = 12 + PFCPNodeReportResponseMessageType MessageType = 13 ) diff --git a/messages/pfcp_association_release.go b/messages/pfcp_association_release.go index e15f91b..07d8716 100644 --- a/messages/pfcp_association_release.go +++ b/messages/pfcp_association_release.go @@ -3,14 +3,12 @@ package messages import "github.com/dot-5g/pfcp/ie" type PFCPAssociationReleaseRequest struct { - SequenceNumber uint32 - NodeID ie.NodeID + NodeID ie.NodeID } type PFCPAssociationReleaseResponse struct { - SequenceNumber uint32 - NodeID ie.NodeID - Cause ie.Cause + NodeID ie.NodeID + Cause ie.Cause } func NewPFCPAssociationReleaseRequest(nodeID ie.NodeID) PFCPAssociationReleaseRequest { diff --git a/messages/pfcp_association_update.go b/messages/pfcp_association_update.go index b5c5102..be4364a 100644 --- a/messages/pfcp_association_update.go +++ b/messages/pfcp_association_update.go @@ -3,14 +3,12 @@ package messages import "github.com/dot-5g/pfcp/ie" type PFCPAssociationUpdateRequest struct { - SequenceNumber uint32 - NodeID ie.NodeID + NodeID ie.NodeID } type PFCPAssociationUpdateResponse struct { - SequenceNumber uint32 - NodeID ie.NodeID - Cause ie.Cause + NodeID ie.NodeID + Cause ie.Cause } func NewPFCPAssociationUpdateRequest(nodeID ie.NodeID) PFCPAssociationUpdateRequest { diff --git a/messages/pfcp_node_report.go b/messages/pfcp_node_report.go new file mode 100644 index 0000000..a9a6513 --- /dev/null +++ b/messages/pfcp_node_report.go @@ -0,0 +1,71 @@ +package messages + +import ( + "github.com/dot-5g/pfcp/ie" +) + +type PFCPNodeReportRequest struct { + NodeID ie.NodeID + NodeReportType ie.NodeReportType +} + +type PFCPNodeReportResponse struct { + NodeID ie.NodeID + Cause ie.Cause +} + +func NewPFCPNodeReportRequest(nodeID ie.NodeID, nodeReportType ie.NodeReportType) PFCPNodeReportRequest { + return PFCPNodeReportRequest{ + NodeID: nodeID, + NodeReportType: nodeReportType, + } +} + +func NewPFCPNodeReportResponse(nodeID ie.NodeID, cause ie.Cause) PFCPNodeReportResponse { + return PFCPNodeReportResponse{ + NodeID: nodeID, + Cause: cause, + } +} + +func ParsePFCPNodeReportRequest(data []byte) (PFCPNodeReportRequest, error) { + ies, err := ie.ParseInformationElements(data) + var nodeID ie.NodeID + var nodeReportType ie.NodeReportType + for _, elem := range ies { + if nodeIDIE, ok := elem.(ie.NodeID); ok { + nodeID = nodeIDIE + continue + } + if nodeReportTypeIE, ok := elem.(ie.NodeReportType); ok { + nodeReportType = nodeReportTypeIE + continue + } + } + + return PFCPNodeReportRequest{ + NodeID: nodeID, + NodeReportType: nodeReportType, + }, err +} + +func ParsePFCPNodeReportResponse(data []byte) (PFCPNodeReportResponse, error) { + ies, err := ie.ParseInformationElements(data) + var nodeID ie.NodeID + var cause ie.Cause + for _, elem := range ies { + if nodeIDIE, ok := elem.(ie.NodeID); ok { + nodeID = nodeIDIE + continue + } + if causeIE, ok := elem.(ie.Cause); ok { + cause = causeIE + continue + } + } + + return PFCPNodeReportResponse{ + NodeID: nodeID, + Cause: cause, + }, err +} diff --git a/server/server.go b/server/server.go index 1cfd22f..8df7fb2 100644 --- a/server/server.go +++ b/server/server.go @@ -16,6 +16,8 @@ type HandlePFCPAssociationUpdateRequest func(sequenceNumber uint32, msg messages type HandlePFCPAssociationUpdateResponse func(sequenceNumber uint32, msg messages.PFCPAssociationUpdateResponse) type HandlePFCPAssociationReleaseRequest func(sequenceNumber uint32, msg messages.PFCPAssociationReleaseRequest) type HandlePFCPAssociationReleaseResponse func(sequenceNumber uint32, msg messages.PFCPAssociationReleaseResponse) +type HandlePFCPNodeReportRequest func(sequenceNumber uint32, msg messages.PFCPNodeReportRequest) +type HandlePFCPNodeReportResponse func(sequenceNumber uint32, msg messages.PFCPNodeReportResponse) type Server struct { address string @@ -29,6 +31,8 @@ type Server struct { pfcpAssociationUpdateResponseHandler HandlePFCPAssociationUpdateResponse pfcpAssociationReleaseRequestHandler HandlePFCPAssociationReleaseRequest pfcpAssociationReleaseResponseHandler HandlePFCPAssociationReleaseResponse + pfcpNodeReportRequestHandler HandlePFCPNodeReportRequest + pfcpNodeReportResponseHandler HandlePFCPNodeReportResponse } func New(address string) *Server { @@ -81,6 +85,14 @@ func (server *Server) PFCPAssociationReleaseResponse(handler HandlePFCPAssociati server.pfcpAssociationReleaseResponseHandler = handler } +func (server *Server) PFCPNodeReportRequest(handler HandlePFCPNodeReportRequest) { + server.pfcpNodeReportRequestHandler = handler +} + +func (server *Server) PFCPNodeReportResponse(handler HandlePFCPNodeReportResponse) { + server.pfcpNodeReportResponseHandler = handler +} + func (server *Server) handleUDPMessage(data []byte) { header, err := headers.ParsePFCPHeader(data[:headers.HeaderSize]) if err != nil { @@ -177,6 +189,28 @@ func (server *Server) handleUDPMessage(data []byte) { return } server.pfcpAssociationReleaseResponseHandler(header.SequenceNumber, msg) + case messages.PFCPNodeReportRequestMessageType: + if server.pfcpNodeReportRequestHandler == nil { + log.Printf("No handler for PFCP Node Report Request") + return + } + msg, err := messages.ParsePFCPNodeReportRequest(data[headers.HeaderSize:]) + if err != nil { + log.Printf("Error parsing PFCP Node Report Request: %v", err) + return + } + server.pfcpNodeReportRequestHandler(header.SequenceNumber, msg) + case messages.PFCPNodeReportResponseMessageType: + if server.pfcpNodeReportResponseHandler == nil { + log.Printf("No handler for PFCP Node Report Response") + return + } + msg, err := messages.ParsePFCPNodeReportResponse(data[headers.HeaderSize:]) + if err != nil { + log.Printf("Error parsing PFCP Node Report Response: %v", err) + return + } + server.pfcpNodeReportResponseHandler(header.SequenceNumber, msg) default: log.Printf("Unknown PFCP message type: %v", header.MessageType) } diff --git a/tests/pfcp_node_report_test.go b/tests/pfcp_node_report_test.go new file mode 100644 index 0000000..224f44a --- /dev/null +++ b/tests/pfcp_node_report_test.go @@ -0,0 +1,189 @@ +package tests + +import ( + "sync" + "testing" + "time" + + "github.com/dot-5g/pfcp/client" + "github.com/dot-5g/pfcp/ie" + "github.com/dot-5g/pfcp/messages" + "github.com/dot-5g/pfcp/server" +) + +var ( + pfcpNodeReportRequestMu sync.Mutex + pfcpNodeReportRequesthandlerCalled bool + pfcpNodeReportRequestReceivedSequenceNumber uint32 + pfcpNodeReportRequestReceivedNodeID ie.NodeID + pfcpNodeReportRequestReceivedNodeReportType ie.NodeReportType +) + +var ( + pfcpNodeReportResponseMu sync.Mutex + pfcpNodeReportResponsehandlerCalled bool + pfcpNodeReportResponseReceivedSequenceNumber uint32 + pfcpNodeReportResponseReceivedNodeID ie.NodeID + pfcpNodeReportResponseReceivedCause ie.Cause +) + +func HandlePFCPNodeReportRequest(sequenceNumber uint32, msg messages.PFCPNodeReportRequest) { + pfcpNodeReportRequestMu.Lock() + defer pfcpNodeReportRequestMu.Unlock() + pfcpNodeReportRequesthandlerCalled = true + pfcpNodeReportRequestReceivedSequenceNumber = sequenceNumber + pfcpNodeReportRequestReceivedNodeID = msg.NodeID + pfcpNodeReportRequestReceivedNodeReportType = msg.NodeReportType +} + +func HandlePFCPNodeReportResponse(sequenceNumber uint32, msg messages.PFCPNodeReportResponse) { + pfcpNodeReportResponseMu.Lock() + defer pfcpNodeReportResponseMu.Unlock() + pfcpNodeReportResponsehandlerCalled = true + pfcpNodeReportResponseReceivedSequenceNumber = sequenceNumber + pfcpNodeReportResponseReceivedNodeID = msg.NodeID + pfcpNodeReportResponseReceivedCause = msg.Cause +} + +func TestPFCPNodeReport(t *testing.T) { + t.Run("TestPFCPNodeReportRequest", PFCPNodeReportRequest) + t.Run("TestPFCPNodeReportResponse", PFCPNodeReportResponse) +} + +func PFCPNodeReportRequest(t *testing.T) { + pfcpServer := server.New("127.0.0.1:8805") + pfcpServer.PFCPNodeReportRequest(HandlePFCPNodeReportRequest) + + pfcpServer.Run() + + defer pfcpServer.Close() + + time.Sleep(time.Second) + pfcpClient := client.New("127.0.0.1:8805") + nodeID := ie.NewNodeID(ie.IPv4, "12.23.34.45") + gpqr := false + ckdr := false + uprr := true + upfr := false + + nodeReportType := ie.NewNodeReportType(gpqr, ckdr, uprr, upfr) + sequenceNumber := uint32(32) + PFCPNodeReportRequestMsg := messages.NewPFCPNodeReportRequest(nodeID, nodeReportType) + + pfcpClient.SendPFCPNodeReportRequest(PFCPNodeReportRequestMsg, sequenceNumber) + + time.Sleep(time.Second) + + pfcpNodeReportRequestMu.Lock() + if !pfcpNodeReportRequesthandlerCalled { + t.Fatalf("PFCP Node Report Request handler was not called") + } + + if pfcpNodeReportRequestReceivedSequenceNumber != sequenceNumber { + t.Errorf("PFCP Node Report Request handler was called with wrong sequence number.\n- Sent sequence number: %v\n- Received sequence number %v\n", sequenceNumber, pfcpNodeReportRequestReceivedSequenceNumber) + } + + if pfcpNodeReportRequestReceivedNodeID.Length != nodeID.Length { + t.Errorf("PFCP Node Report Request handler was called with wrong node ID length.\n- Sent node ID length: %v\n- Received node ID length %v\n", nodeID.Length, pfcpNodeReportRequestReceivedNodeID.Length) + } + + if pfcpNodeReportRequestReceivedNodeID.NodeIDType != nodeID.NodeIDType { + t.Errorf("PFCP Node Report Request handler was called with wrong node ID type.\n- Sent node ID type: %v\n- Received node ID type %v\n", nodeID.NodeIDType, pfcpNodeReportRequestReceivedNodeID.NodeIDType) + } + + if len(pfcpNodeReportRequestReceivedNodeID.NodeIDValue) != len(nodeID.NodeIDValue) { + t.Errorf("PFCP Node Report Request handler was called with wrong node ID value length.\n- Sent node ID value length: %v\n- Received node ID value length %v\n", len(nodeID.NodeIDValue), len(pfcpNodeReportRequestReceivedNodeID.NodeIDValue)) + } + + for i := range nodeID.NodeIDValue { + if pfcpNodeReportRequestReceivedNodeID.NodeIDValue[i] != nodeID.NodeIDValue[i] { + t.Errorf("PFCP Node Report Request handler was called with wrong node ID value.\n- Sent node ID value: %v\n- Received node ID value %v\n", nodeID.NodeIDValue, pfcpNodeReportRequestReceivedNodeID.NodeIDValue) + } + } + + if pfcpNodeReportRequestReceivedNodeReportType.Length != nodeReportType.Length { + t.Errorf("PFCP Node Report Request handler was called with wrong node report type length.\n- Sent node report type length: %v\n- Received node report type length %v\n", nodeReportType.Length, pfcpNodeReportRequestReceivedNodeReportType.Length) + } + + if pfcpNodeReportRequestReceivedNodeReportType.IEtype != nodeReportType.IEtype { + t.Errorf("PFCP Node Report Request handler was called with wrong node report type type.\n- Sent node report type type: %v\n- Received node report type type %v\n", nodeReportType.IEtype, pfcpNodeReportRequestReceivedNodeReportType.IEtype) + } + + if pfcpNodeReportRequestReceivedNodeReportType.GPQR != nodeReportType.GPQR { + t.Errorf("PFCP Node Report Request handler was called with wrong node report type GPQR.\n- Sent node report type GPQR: %v\n- Received node report type GPQR %v\n", nodeReportType.GPQR, pfcpNodeReportRequestReceivedNodeReportType.GPQR) + } + + if pfcpNodeReportRequestReceivedNodeReportType.CKDR != nodeReportType.CKDR { + t.Errorf("PFCP Node Report Request handler was called with wrong node report type CKDR.\n- Sent node report type CKDR: %v\n- Received node report type CKDR %v\n", nodeReportType.CKDR, pfcpNodeReportRequestReceivedNodeReportType.CKDR) + } + + if pfcpNodeReportRequestReceivedNodeReportType.UPRR != nodeReportType.UPRR { + t.Errorf("PFCP Node Report Request handler was called with wrong node report type UPRR.\n- Sent node report type UPRR: %v\n- Received node report type UPRR %v\n", nodeReportType.UPRR, pfcpNodeReportRequestReceivedNodeReportType.UPRR) + } + + if pfcpNodeReportRequestReceivedNodeReportType.UPFR != nodeReportType.UPFR { + t.Errorf("PFCP Node Report Request handler was called with wrong node report type UPFR.\n- Sent node report type UPFR: %v\n- Received node report type UPFR %v\n", nodeReportType.UPFR, pfcpNodeReportRequestReceivedNodeReportType.UPFR) + } + + pfcpNodeReportRequestMu.Unlock() +} + +func PFCPNodeReportResponse(t *testing.T) { + pfcpServer := server.New("127.0.0.1:8805") + pfcpServer.PFCPNodeReportResponse(HandlePFCPNodeReportResponse) + + pfcpServer.Run() + + defer pfcpServer.Close() + + time.Sleep(time.Second) + pfcpClient := client.New("127.0.0.1:8805") + nodeID := ie.NewNodeID(ie.IPv4, "3.4.5.6") + sequenceNumber := uint32(32) + cause := ie.NewCause(2) + PFCPNodeReportResponseMsg := messages.NewPFCPNodeReportResponse(nodeID, cause) + + pfcpClient.SendPFCPNodeReportResponse(PFCPNodeReportResponseMsg, sequenceNumber) + + time.Sleep(time.Second) + + pfcpNodeReportResponseMu.Lock() + if !pfcpNodeReportResponsehandlerCalled { + t.Fatalf("PFCP Node Report Response handler was not called") + } + + if pfcpNodeReportResponseReceivedSequenceNumber != sequenceNumber { + t.Errorf("PFCP Node Report Response handler was called with wrong sequence number.\n- Sent sequence number: %v\n- Received sequence number %v\n", sequenceNumber, pfcpNodeReportResponseReceivedSequenceNumber) + } + + if pfcpNodeReportResponseReceivedNodeID.Length != nodeID.Length { + t.Errorf("PFCP Node Report Response handler was called with wrong node ID length.\n- Sent node ID length: %v\n- Received node ID length %v\n", nodeID.Length, pfcpNodeReportResponseReceivedNodeID.Length) + } + + if pfcpNodeReportResponseReceivedNodeID.NodeIDType != nodeID.NodeIDType { + t.Errorf("PFCP Node Report Response handler was called with wrong node ID type.\n- Sent node ID type: %v\n- Received node ID type %v\n", nodeID.NodeIDType, pfcpNodeReportResponseReceivedNodeID.NodeIDType) + } + + if len(pfcpNodeReportResponseReceivedNodeID.NodeIDValue) != len(nodeID.NodeIDValue) { + t.Errorf("PFCP Node Report Response handler was called with wrong node ID value length.\n- Sent node ID value length: %v\n- Received node ID value length %v\n", len(nodeID.NodeIDValue), len(pfcpNodeReportResponseReceivedNodeID.NodeIDValue)) + } + + for i := range nodeID.NodeIDValue { + if pfcpNodeReportResponseReceivedNodeID.NodeIDValue[i] != nodeID.NodeIDValue[i] { + t.Errorf("PFCP Node Report Response handler was called with wrong node ID value.\n- Sent node ID value: %v\n- Received node ID value %v\n", nodeID.NodeIDValue, pfcpNodeReportResponseReceivedNodeID.NodeIDValue) + } + } + + if pfcpNodeReportResponseReceivedCause.Length != cause.Length { + t.Errorf("PFCP Node Report Response handler was called with wrong cause length.\n- Sent cause length: %v\n- Received cause length %v\n", cause.Length, pfcpNodeReportResponseReceivedCause.Length) + } + + if pfcpNodeReportResponseReceivedCause.IEtype != cause.IEtype { + t.Errorf("PFCP Node Report Response handler was called with wrong cause type.\n- Sent cause type: %v\n- Received cause type %v\n", cause.IEtype, pfcpNodeReportResponseReceivedCause.IEtype) + } + + if pfcpNodeReportResponseReceivedCause.Value != cause.Value { + t.Errorf("PFCP Node Report Response handler was called with wrong cause value.\n- Sent cause value: %v\n- Received cause value %v\n", cause.Value, pfcpNodeReportResponseReceivedCause.Value) + } + +}