Skip to content

Commit

Permalink
(wip) Add handover; close #8; close #9; close #10; close #11; close #12
Browse files Browse the repository at this point in the history
  • Loading branch information
louisroyer committed Dec 23, 2024
1 parent d412e64 commit 2ba4003
Show file tree
Hide file tree
Showing 13 changed files with 407 additions and 49 deletions.
14 changes: 7 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.22.7
require (
github.com/adrg/xdg v0.5.3
github.com/gin-gonic/gin v1.10.0
github.com/nextmn/json-api v0.0.14
github.com/nextmn/json-api v0.0.15-0.20241223192440-30b4537ace9e
github.com/nextmn/logrus-formatter v0.0.1
github.com/sirupsen/logrus v1.9.3
github.com/urfave/cli/v2 v2.27.5
Expand All @@ -14,7 +14,7 @@ require (
)

require (
github.com/bytedance/sonic v1.12.5 // indirect
github.com/bytedance/sonic v1.12.6 // indirect
github.com/bytedance/sonic/loader v0.2.1 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
Expand All @@ -24,7 +24,7 @@ require (
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.23.0 // indirect
github.com/goccy/go-json v0.10.3 // indirect
github.com/goccy/go-json v0.10.4 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
Expand All @@ -39,9 +39,9 @@ require (
github.com/vishvananda/netns v0.0.5 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
golang.org/x/arch v0.12.0 // indirect
golang.org/x/crypto v0.29.0 // indirect
golang.org/x/net v0.31.0 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.20.0 // indirect
google.golang.org/protobuf v1.35.2 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/protobuf v1.36.0 // indirect
)
40 changes: 26 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78=
github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ=
github.com/bytedance/sonic v1.12.5 h1:hoZxY8uW+mT+OpkcUWw4k0fDINtOcVavEsGfzwzFU/w=
github.com/bytedance/sonic v1.12.5/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
github.com/bytedance/sonic v1.12.6 h1:/isNmCUF2x3Sh8RAp/4mh4ZGkcFAX/hLrzrK3AvpRzk=
github.com/bytedance/sonic v1.12.6/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E=
github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
Expand All @@ -28,8 +28,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o=
github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM=
github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
Expand All @@ -48,8 +48,20 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/nextmn/json-api v0.0.14 h1:m4uHOVcXsxkXoxbrhqemLTRG4T86eYkejjirew1nDUU=
github.com/nextmn/json-api v0.0.14/go.mod h1:CQXeNPj9MDGsEExtnqJFIGjLgZAKsmOoO2fy+mep7Ak=
github.com/nextmn/json-api v0.0.15-0.20241218142156-a64418a36b7d h1:lhybNMDI+qjJB+rKDgJiHrXuhkoR7FWhQ4nEfpqZy1g=
github.com/nextmn/json-api v0.0.15-0.20241218142156-a64418a36b7d/go.mod h1:CQXeNPj9MDGsEExtnqJFIGjLgZAKsmOoO2fy+mep7Ak=
github.com/nextmn/json-api v0.0.15-0.20241223150142-2189fb1dc3af h1:/YGOPznGEQ0x/2E1Yk9HZ/3FosWtK5FouI0NDSiN2sE=
github.com/nextmn/json-api v0.0.15-0.20241223150142-2189fb1dc3af/go.mod h1:CQXeNPj9MDGsEExtnqJFIGjLgZAKsmOoO2fy+mep7Ak=
github.com/nextmn/json-api v0.0.15-0.20241223151312-9ece63d06e84 h1:eMjBBW9K21ffZ0CmbY7nKZd8d7O41DMB10t2HOTkUHw=
github.com/nextmn/json-api v0.0.15-0.20241223151312-9ece63d06e84/go.mod h1:CQXeNPj9MDGsEExtnqJFIGjLgZAKsmOoO2fy+mep7Ak=
github.com/nextmn/json-api v0.0.15-0.20241223184721-e18ca5cd5f80 h1:bCHBRPROQR9S31nyqTSMuC3GQ0sENbv0976+v28IdnY=
github.com/nextmn/json-api v0.0.15-0.20241223184721-e18ca5cd5f80/go.mod h1:CQXeNPj9MDGsEExtnqJFIGjLgZAKsmOoO2fy+mep7Ak=
github.com/nextmn/json-api v0.0.15-0.20241223190836-9214d6edc562 h1:J7A9dVo41ZUc2Df+Ri58I5fwNdmlPmy0/WfNHi0nmjE=
github.com/nextmn/json-api v0.0.15-0.20241223190836-9214d6edc562/go.mod h1:CQXeNPj9MDGsEExtnqJFIGjLgZAKsmOoO2fy+mep7Ak=
github.com/nextmn/json-api v0.0.15-0.20241223192051-3fc04f155386 h1:RP6Vc+ITbrH6JhBKLGn41eIcttP46gI2g6Inu65BvRY=
github.com/nextmn/json-api v0.0.15-0.20241223192051-3fc04f155386/go.mod h1:CQXeNPj9MDGsEExtnqJFIGjLgZAKsmOoO2fy+mep7Ak=
github.com/nextmn/json-api v0.0.15-0.20241223192440-30b4537ace9e h1:yDqGoYWiSbG5Ca869nEQN7i9OY77JowwGruBmn2fn+w=
github.com/nextmn/json-api v0.0.15-0.20241223192440-30b4537ace9e/go.mod h1:CQXeNPj9MDGsEExtnqJFIGjLgZAKsmOoO2fy+mep7Ak=
github.com/nextmn/logrus-formatter v0.0.1 h1:Bsf78jjiEESc+rV8xE6IyKj4frDPGMwXFNrLQzm6A1E=
github.com/nextmn/logrus-formatter v0.0.1/go.mod h1:vdSZ+sIcSna8vjbXkSFxsnsKHqRwaUEed4JCPcXoGyM=
github.com/pascaldekloe/goe v0.1.1 h1:Ah6WQ56rZONR3RW3qWa2NCZ6JAVvSpUcoLBaOmYFt9Q=
Expand Down Expand Up @@ -89,20 +101,20 @@ github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGC
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
golang.org/x/arch v0.12.0 h1:UsYJhbzPYGsT0HbEdmYcqtCv8UNGvnaL561NnIUvaKg=
golang.org/x/arch v0.12.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ=
google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
5 changes: 5 additions & 0 deletions internal/app/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"net/netip"
"time"

"github.com/nextmn/gnb-lite/internal/cli"
"github.com/nextmn/gnb-lite/internal/radio"
"github.com/nextmn/gnb-lite/internal/session"

Expand All @@ -29,10 +30,14 @@ type HttpServerEntity struct {
}

func NewHttpServerEntity(bindAddr netip.AddrPort, r *radio.Radio, ps *session.PduSessions) *HttpServerEntity {
c := cli.NewCli(r, ps)
// TODO: gin.SetMode(gin.DebugMode) / gin.SetMode(gin.ReleaseMode) depending on log level
h := gin.Default()
h.GET("/status", Status)

// CLI
c.Register(h)

// Radio
r.Register(h)

Expand Down
29 changes: 29 additions & 0 deletions internal/cli/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2024 Louis Royer and the NextMN contributors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// SPDX-License-Identifier: MIT

package cli

import (
"github.com/nextmn/gnb-lite/internal/radio"
"github.com/nextmn/gnb-lite/internal/session"

"github.com/gin-gonic/gin"
)

type Cli struct {
Radio *radio.Radio
PduSessions *session.PduSessions
}

func NewCli(r *radio.Radio, p *session.PduSessions) *Cli {
return &Cli{
Radio: r,
PduSessions: p,
}
}

func (cli *Cli) Register(e *gin.Engine) {
e.POST("/cli/ps/handover", cli.PsHandover)
}
58 changes: 58 additions & 0 deletions internal/cli/ps-handover.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2024 Louis Royer and the NextMN contributors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// SPDX-License-Identifier: MIT

package cli

import (
"bytes"
"encoding/json"
"net/http"

"github.com/nextmn/json-api/jsonapi"
"github.com/nextmn/json-api/jsonapi/n1n2"

"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)

type PsHandover struct {
UeCtrl jsonapi.ControlURI `json:"ue-ctrl"`
GNBTarget jsonapi.ControlURI `json:"gnb-target"`
Sessions []n1n2.Session `json:"sessions"`
}

func (cli *Cli) PsHandover(c *gin.Context) {
var ps PsHandover
if err := c.BindJSON(&ps); err != nil {
logrus.WithError(err).Error("could not deserialize")
c.JSON(http.StatusBadRequest, jsonapi.MessageWithError{Message: "could not deserialize", Error: err})
}
go cli.HandlePsHandover(ps)
c.Status(http.StatusNotImplemented)
}

func (cli *Cli) HandlePsHandover(ps PsHandover) {
ctx := cli.PduSessions.Context()
hr := n1n2.HandoverRequired{
SourcegNB: cli.PduSessions.Control,
Ue: ps.UeCtrl,
}
reqBody, err := json.Marshal(hr)
if err != nil {
logrus.WithError(err).Error("Could not marshal n1n2.HandoverRequired")
return
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, cli.PduSessions.Cp.JoinPath("ps/handover-required").String(), bytes.NewBuffer(reqBody))
if err != nil {
logrus.WithError(err).Error("Could not create ps/handover-required")
return
}
req.Header.Set("User-Agent", cli.PduSessions.UserAgent)
req.Header.Set("Content-Type", "application/json; charset=UTF-8")
if _, err := cli.PduSessions.Client.Do(req); err != nil {
logrus.WithError(err).Error("Could not send ps/handover-required")
return
}
}
11 changes: 9 additions & 2 deletions internal/gtp/gtp.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (gtp *Gtp) Start(ctx context.Context) error {
uConn := gtpv1.NewUPlaneConn(laddr)
uConn.DisableErrorIndication()
uConn.AddHandler(message.MsgTypeTPDU, func(c gtpv1.Conn, senderAddr net.Addr, msg message.Message) error {
return gtp.tpduHandler(c, senderAddr, msg)
return gtp.tpduHandler(ctx, c, senderAddr, msg)
})
go func(ctx context.Context) error {
defer close(gtp.closed)
Expand All @@ -59,8 +59,15 @@ func (gtp *Gtp) Start(ctx context.Context) error {
}

// handle GTP PDU (Downlink)
func (gtp *Gtp) tpduHandler(c gtpv1.Conn, senderAddr net.Addr, msg message.Message) error {
func (gtp *Gtp) tpduHandler(ctx context.Context, c gtpv1.Conn, senderAddr net.Addr, msg message.Message) error {
teid := msg.TEID()
// Try forwarding downlink (handover)
if fd, err := gtp.psMan.GetForwarding(teid); err == nil {
packet := msg.(*message.TPDU).Decapsulate()
return gtp.psMan.ForwardUplink(ctx, packet, fd)
}

// Try to forward to UE over radio
ue, err := gtp.psMan.GetUECtrl(teid)
if err != nil {
return err
Expand Down
5 changes: 3 additions & 2 deletions internal/session/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
var (
ErrNilCtx = errors.New("nil context")

ErrUnsupportedPDUType = errors.New("Unsupported PDU type")
ErrPduSessionNotFound = errors.New("PDU Session not found")
ErrUnsupportedPDUType = errors.New("Unsupported PDU type")
ErrPduSessionNotFound = errors.New("PDU Session not found")
ErrForwardDownlinkNotFound = errors.New("Forward Downlink rule not found")
)
65 changes: 65 additions & 0 deletions internal/session/handover_command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright 2024 Louis Royer and the NextMN contributors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// SPDX-License-Identifier: MIT

package session

import (
"bytes"
"encoding/json"
"net/http"

"github.com/nextmn/json-api/jsonapi"
"github.com/nextmn/json-api/jsonapi/n1n2"

"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)

func (s *PduSessions) HandoverCommand(c *gin.Context) {
var ps n1n2.HandoverCommand
if err := c.BindJSON(&ps); err != nil {
logrus.WithError(err).Error("could not deserialize")
c.JSON(http.StatusBadRequest, jsonapi.MessageWithError{Message: "could not deserialize", Error: err})
return
}
logrus.WithFields(logrus.Fields{
"ue": ps.UeCtrl.String(),
}).Info("New Handover Command")
go s.HandleHandoverCommand(ps)
c.JSON(http.StatusAccepted, jsonapi.Message{Message: "please refer to logs for more information"})
}

func (s *PduSessions) HandleHandoverCommand(ps n1n2.HandoverCommand) {
// Add forwarder for downlink
for _, session := range ps.Sessions {
if session.ForwardDownlinkFteid == nil || session.DownlinkFteid == nil {
// TODO: notify CP of error
continue
}
s.manager.ForwardDownlink[session.DownlinkFteid.Teid] = session.ForwardDownlinkFteid
// TODO: remove downlink forward with a timer
// TODO: remove pdu session after a timer
}

ctx := s.Context()
// Forward to UE
reqBody, err := json.Marshal(ps)
if err != nil {
logrus.WithError(err).Error("Could not marshal n1n2.HandoverCommand")
return
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, ps.UeCtrl.JoinPath("ps/handover-command").String(), bytes.NewBuffer(reqBody))
if err != nil {
logrus.WithError(err).Error("Could not create ps/handover-command")
return
}
req.Header.Set("User-Agent", s.UserAgent)
req.Header.Set("Content-Type", "application/json; charset=UTF-8")
if _, err := s.Client.Do(req); err != nil {
logrus.WithError(err).Error("Could not send ps/handover-command")
return
}

}
62 changes: 62 additions & 0 deletions internal/session/handover_confirm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2024 Louis Royer and the NextMN contributors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// SPDX-License-Identifier: MIT

package session

import (
"bytes"
"encoding/json"
"net/http"

"github.com/nextmn/json-api/jsonapi"
"github.com/nextmn/json-api/jsonapi/n1n2"

"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)

func (s *PduSessions) HandoverConfirm(c *gin.Context) {
var ps n1n2.HandoverConfirm
if err := c.BindJSON(&ps); err != nil {
logrus.WithError(err).Error("could not deserialize")
c.JSON(http.StatusBadRequest, jsonapi.MessageWithError{Message: "could not deserialize", Error: err})
return
}
logrus.WithFields(logrus.Fields{
"ue": ps.UeCtrl.String(),
}).Info("New Handover Confirm")
go s.HandleHandoverConfirm(ps)
c.JSON(http.StatusAccepted, jsonapi.Message{Message: "please refer to logs for more information"})
}

func (s *PduSessions) HandleHandoverConfirm(ps n1n2.HandoverConfirm) {
ctx := s.Context()
// forward to CP
resp := n1n2.HandoverNotify{
// Header
UeCtrl: ps.UeCtrl,
Cp: ps.Cp,
TargetGnb: ps.TargetGnb,
// Handover Notify
Sessions: ps.Sessions,
SourceGnb: ps.SourceGnb,
}
reqBody, err := json.Marshal(resp)
if err != nil {
logrus.WithError(err).Error("Could not marshal n1n2.HandoverNotify")
return
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, s.Cp.JoinPath("ps/handover-notify").String(), bytes.NewBuffer(reqBody))
if err != nil {
logrus.WithError(err).Error("Could not create ps/handover-notify")
return
}
req.Header.Set("User-Agent", s.UserAgent)
req.Header.Set("Content-Type", "application/json; charset=UTF-8")
if _, err := s.Client.Do(req); err != nil {
logrus.WithError(err).Error("Could not send ps/handover-notify")
return
}
}
Loading

0 comments on commit 2ba4003

Please sign in to comment.