Skip to content
This repository has been archived by the owner on Oct 20, 2024. It is now read-only.

Commit

Permalink
feat: Adds pfcp association request response
Browse files Browse the repository at this point in the history
  • Loading branch information
gruyaume committed Dec 25, 2023
1 parent 70725cb commit 74af19e
Show file tree
Hide file tree
Showing 13 changed files with 448 additions and 256 deletions.
25 changes: 19 additions & 6 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"log"

"github.com/dot-5g/pfcp/headers"
"github.com/dot-5g/pfcp/ie"
"github.com/dot-5g/pfcp/messages"
"github.com/dot-5g/pfcp/network"
Expand All @@ -23,7 +24,7 @@ func New(ServerAddress string) *Pfcp {
return &Pfcp{ServerAddress: ServerAddress, Udp: udpClient}
}

func (pfcp *Pfcp) sendPfcpMessage(header messages.PFCPHeader, elements []ie.InformationElement) error {
func (pfcp *Pfcp) sendPfcpMessage(header headers.PFCPHeader, elements []ie.InformationElement) error {
var payload []byte
for _, element := range elements {
payload = append(payload, element.Serialize()...)
Expand All @@ -37,14 +38,14 @@ func (pfcp *Pfcp) sendPfcpMessage(header messages.PFCPHeader, elements []ie.Info
return nil
}

func serializeMessage(header messages.PFCPHeader, payload []byte) []byte {
func serializeMessage(header headers.PFCPHeader, payload []byte) []byte {
header.MessageLength = uint16(4 + len(payload))
headerBytes := messages.SerializePFCPHeader(header)
headerBytes := headers.SerializePFCPHeader(header)
return append(headerBytes, payload...)
}

func (pfcp *Pfcp) SendHeartbeatRequest(recoveryTimeStamp ie.RecoveryTimeStamp, sequenceNumber uint32) (ie.RecoveryTimeStamp, error) {
header := messages.NewPFCPHeader(messages.PFCPHeartbeatRequest, sequenceNumber)
header := headers.NewPFCPHeader(messages.PFCPHeartbeatRequest, sequenceNumber)
payload := []ie.InformationElement{recoveryTimeStamp}
err := pfcp.sendPfcpMessage(header, payload)
if err != nil {
Expand All @@ -54,7 +55,7 @@ func (pfcp *Pfcp) SendHeartbeatRequest(recoveryTimeStamp ie.RecoveryTimeStamp, s
}

func (pfcp *Pfcp) SendHeartbeatResponse(recoveryTimeStamp ie.RecoveryTimeStamp, sequenceNumber uint32) (ie.RecoveryTimeStamp, error) {
header := messages.NewPFCPHeader(messages.PFCPHeartbeatResponse, sequenceNumber)
header := headers.NewPFCPHeader(messages.PFCPHeartbeatResponse, sequenceNumber)
payload := []ie.InformationElement{recoveryTimeStamp}
err := pfcp.sendPfcpMessage(header, payload)
if err != nil {
Expand All @@ -64,11 +65,23 @@ func (pfcp *Pfcp) SendHeartbeatResponse(recoveryTimeStamp ie.RecoveryTimeStamp,
}

func (pfcp *Pfcp) SendPFCPAssociationSetupRequest(nodeID ie.NodeID, recoveryTimeStamp ie.RecoveryTimeStamp, sequenceNumber uint32) error {
header := messages.NewPFCPHeader(messages.PFCPAssociationSetupRequest, sequenceNumber)
header := headers.NewPFCPHeader(messages.PFCPAssociationSetupRequest, sequenceNumber)
payload := []ie.InformationElement{nodeID, recoveryTimeStamp}
err := pfcp.sendPfcpMessage(header, payload)
if err != nil {
return fmt.Errorf("error sending PFCP Association Setup Request: %w", err)
}
return nil
}

func (pfcp *Pfcp) SendPFCPAssociationSetupResponse(nodeID ie.NodeID, cause ie.Cause, recoveryTimeStamp ie.RecoveryTimeStamp, sequenceNumber uint32) error {
header := headers.NewPFCPHeader(messages.PFCPAssociationSetupResponse, sequenceNumber)
payload := []ie.InformationElement{nodeID, cause, recoveryTimeStamp}
err := pfcp.sendPfcpMessage(header, payload)
if err != nil {
return fmt.Errorf("error sending PFCP Association Setup Response: %w", err)
}
fmt.Printf("PFCP Association Setup Response sent successfully to %s.\n", pfcp.ServerAddress)
fmt.Printf("Payload: %v\n", payload)
return nil
}
29 changes: 5 additions & 24 deletions messages/header.go → headers/header.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package messages
package headers

import (
"bytes"
"encoding/binary"
"fmt"

"github.com/dot-5g/pfcp/messages"
)

type PFCPHeader struct {
Expand All @@ -13,14 +15,6 @@ type PFCPHeader struct {
SequenceNumber uint32
}

type PFCPMessageType int

const (
PFCPHeartbeatRequest PFCPMessageType = iota
PFCPHeartbeatResponse
PFCPAssociationSetupRequest
)

func SerializePFCPHeader(header PFCPHeader) []byte {
buf := new(bytes.Buffer)

Expand All @@ -45,23 +39,10 @@ func SerializePFCPHeader(header PFCPHeader) []byte {
return buf.Bytes()
}

func messageTypeToByte(messageType PFCPMessageType) byte {
switch messageType {
case PFCPHeartbeatRequest:
return 1
case PFCPHeartbeatResponse:
return 2
case PFCPAssociationSetupRequest:
return 5
default:
return 0
}
}

func NewPFCPHeader(messageType PFCPMessageType, sequenceNumber uint32) PFCPHeader {
func NewPFCPHeader(messageType messages.PFCPMessageType, sequenceNumber uint32) PFCPHeader {
return PFCPHeader{
Version: 1,
MessageType: messageTypeToByte(messageType),
MessageType: messages.MessageTypeToByte(messageType),
MessageLength: 0, // To be set later
SequenceNumber: sequenceNumber,
}
Expand Down
8 changes: 4 additions & 4 deletions messages/header_test.go → headers/header_test.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
package messages_test
package headers_test

import (
"bytes"
"encoding/binary"
"testing"

"github.com/dot-5g/pfcp/messages"
"github.com/dot-5g/pfcp/headers"
)

func TestGivenPfcpHeaderWhenSerializePFCPHeaderThenSerializedCorrectly(t *testing.T) {
pfcpHeader := messages.PFCPHeader{
pfcpHeader := headers.PFCPHeader{
Version: 1,
MessageType: 2,
MessageLength: 3,
SequenceNumber: 4,
}

headerBytes := messages.SerializePFCPHeader(pfcpHeader)
headerBytes := headers.SerializePFCPHeader(pfcpHeader)

if len(headerBytes) != 8 {
t.Errorf("Expected 8 bytes, got %d", len(headerBytes))
Expand Down
43 changes: 43 additions & 0 deletions ie/cause.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package ie

import (
"bytes"
"encoding/binary"
)

type Cause struct {
Type uint16
Length uint16
Value uint8
}

func NewCause(value int) Cause {
return Cause{
Type: 19,
Length: 1,
Value: uint8(value),
}
}

func (cause Cause) Serialize() []byte {
buf := new(bytes.Buffer)

// Octets 1 to 2: Type
binary.Write(buf, binary.BigEndian, uint16(cause.Type))

// Octets 3 to 4: Length
binary.Write(buf, binary.BigEndian, uint16(cause.Length))

// Octet 5: Value (1 byte)
buf.WriteByte(cause.Value)

return buf.Bytes()
}

func DeserializeCause(ieType uint16, ieLength uint16, ieValue []byte) Cause {
return Cause{
Type: ieType,
Length: ieLength,
Value: ieValue[0],
}
}
2 changes: 2 additions & 0 deletions ie/ie.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ func ParseInformationElements(b []byte) ([]InformationElement, error) {
ieValue := b[index : index+int(ieLength)]
var ie InformationElement
switch ieType {
case 19:
ie = DeserializeCause(ieType, ieLength, ieValue)
case 60:
ie = DeserializeNodeID(ieType, ieLength, ieValue)
case 96:
Expand Down
2 changes: 0 additions & 2 deletions ie/nodeId.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,6 @@ func (n NodeID) Serialize() []byte {
// Octets 6 to n+5: Node ID Value
buf.Write(n.NodeIDValue)

fmt.Printf("Node ID - serialized: %v\n", buf.Bytes())

return buf.Bytes()
}

Expand Down
177 changes: 0 additions & 177 deletions main_test.go

This file was deleted.

Loading

0 comments on commit 74af19e

Please sign in to comment.