catalog 实现
sipgo udp MTU 1500 限制, 数据包大于 1500 会报错
This commit is contained in:
parent
c18573d730
commit
eb1219c2fe
@ -1,26 +1,42 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"encoding/xml"
|
||||
"git.skcks.cn/Shikong/go-gb28181/pkg/config"
|
||||
"git.skcks.cn/Shikong/go-gb28181/pkg/logger"
|
||||
"git.skcks.cn/Shikong/go-gb28181/pkg/manscdp"
|
||||
"git.skcks.cn/Shikong/go-gb28181/pkg/utils"
|
||||
"github.com/emiago/sipgo"
|
||||
"github.com/emiago/sipgo/sip"
|
||||
"github.com/rs/zerolog"
|
||||
"time"
|
||||
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func main() {
|
||||
output := zerolog.NewConsoleWriter(func(w *zerolog.ConsoleWriter) {
|
||||
w.Out = os.Stdout
|
||||
w.TimeFormat = time.RFC3339
|
||||
})
|
||||
logger := zerolog.New(output).With().Timestamp().Logger()
|
||||
|
||||
clientConfig, err := config.ReadClientConfig()
|
||||
if err != nil {
|
||||
logger.Log().Fatal(err)
|
||||
logger.Fatal().Any("%s", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("%+v\n", clientConfig)
|
||||
|
||||
sip.SIPDebug = clientConfig.Debug
|
||||
if clientConfig.Debug {
|
||||
sip.SIPDebug = clientConfig.Debug
|
||||
logger = logger.Level(zerolog.DebugLevel)
|
||||
} else {
|
||||
logger = logger.Level(zerolog.InfoLevel)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
@ -29,19 +45,92 @@ func main() {
|
||||
sipgo.WithUserAgent(clientConfig.DeviceId),
|
||||
sipgo.WithUserAgentHostname(addr))
|
||||
|
||||
srv, _ := sipgo.NewServer(ua)
|
||||
srv, _ := sipgo.NewServer(ua, sipgo.WithServerLogger(logger))
|
||||
|
||||
srv.OnMessage(func(req *sip.Request, tx sip.ServerTransaction) {
|
||||
query := new(manscdp.CatalogReq)
|
||||
_ = utils.XMLUnmarshal(req.Body(), query)
|
||||
logger.Info().Msgf("收到查询指令: %s\n%+v\n", query.CmdType, query)
|
||||
|
||||
//response := sip.NewResponse(sip.StatusOK, "OK")
|
||||
//err = tx.Respond(response)
|
||||
//if err != nil {
|
||||
// logger.Error().Err(err)
|
||||
//}
|
||||
tx.Done()
|
||||
|
||||
go func() {
|
||||
client, _ := sipgo.NewClient(ua,
|
||||
sipgo.WithClientHostname(clientConfig.ListenIp),
|
||||
sipgo.WithClientPort(clientConfig.ListenPort))
|
||||
|
||||
resp := new(manscdp.CatalogResp)
|
||||
resp.XMLName = xml.Name{Local: "Response"}
|
||||
resp.DeviceID = clientConfig.DeviceId
|
||||
resp.CmdType = "Catalog"
|
||||
resp.SumNum = "1"
|
||||
resp.DeviceList = new(manscdp.CateLogDeviceList)
|
||||
resp.DeviceList.XMLName = xml.Name{Local: "DeviceList"}
|
||||
resp.DeviceList.Num = "1"
|
||||
resp.DeviceList.Item = make([]manscdp.CateLogDevice, 1)
|
||||
resp.DeviceList.Item[0].DeviceID = "44050100002000000002"
|
||||
resp.DeviceList.Item[0].Name = "设备名称"
|
||||
resp.DeviceList.Item[0].Manufacturer = "设备厂商"
|
||||
resp.DeviceList.Item[0].ErrCode = "0"
|
||||
resp.DeviceList.Item[0].Port = fmt.Sprintf("%d", clientConfig.ListenPort)
|
||||
|
||||
resp.SN = query.SN
|
||||
|
||||
marshal, _ := utils.XMLMarshal(resp, "gbk")
|
||||
logger.Info().Msgf("回复查询指令: %s\n%+v\n", query.CmdType, resp)
|
||||
|
||||
target := sip.Uri{
|
||||
User: clientConfig.ServerId,
|
||||
Host: clientConfig.ServerIp,
|
||||
Port: clientConfig.ServerPort,
|
||||
Headers: sip.NewParams(),
|
||||
}
|
||||
|
||||
time.Sleep(time.Second * 1)
|
||||
//uri := sip.Uri{User: "44050100002000000002", Host: "10.10.10.20", Port: 5099}
|
||||
nReq := sip.NewRequest(sip.MESSAGE, target)
|
||||
nReq.SetTransport("UDP")
|
||||
to := sip.NewHeader("To", req.GetHeader("From").Value())
|
||||
from := sip.NewHeader("From", req.GetHeader("To").Value())
|
||||
nReq.AppendHeader(to)
|
||||
nReq.AppendHeader(from)
|
||||
//nReq.AppendHeader(req.GetHeader("Call-ID"))
|
||||
nReq.AppendHeader(sip.NewHeader("Content-Type", "Application/MANSCDP+xml"))
|
||||
|
||||
nReq.SetBody(marshal)
|
||||
err := sipgo.ClientRequestBuild(client, nReq)
|
||||
if err != nil {
|
||||
logger.Error().Err(err)
|
||||
}
|
||||
|
||||
logger.Info().Msgf("向服务器发送查询指令: %s\n%+v\n", query.CmdType, nReq)
|
||||
|
||||
err = client.WriteRequest(nReq)
|
||||
if err != nil {
|
||||
logger.Error().Err(err)
|
||||
return
|
||||
}
|
||||
_ = client.Close()
|
||||
logger.Info().Msgf("向服务器发送查询指令完成")
|
||||
}()
|
||||
})
|
||||
|
||||
quit := make(chan os.Signal, 1)
|
||||
go func() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
logger.Log().Error(err)
|
||||
logger.Fatal().Any("%s", err)
|
||||
quit <- syscall.SIGKILL
|
||||
}
|
||||
}()
|
||||
|
||||
if err := srv.ListenAndServe(ctx, "udp", addr); err != nil {
|
||||
logger.Log().Error(err)
|
||||
logger.Error().Err(err)
|
||||
quit <- syscall.SIGTERM
|
||||
}
|
||||
}()
|
||||
|
1
go.mod
1
go.mod
@ -4,7 +4,6 @@ go 1.23.5
|
||||
|
||||
require (
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394
|
||||
github.com/duke-git/lancet/v2 v2.3.4
|
||||
github.com/emiago/sipgo v0.28.0
|
||||
github.com/icholy/digest v1.1.0
|
||||
github.com/pelletier/go-toml/v2 v2.2.2
|
||||
|
2
go.sum
2
go.sum
@ -7,8 +7,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/duke-git/lancet/v2 v2.3.4 h1:8XGI7P9w+/GqmEBEXYaH/XuNiM0f4/90Ioti0IvYJls=
|
||||
github.com/duke-git/lancet/v2 v2.3.4/go.mod h1:zGa2R4xswg6EG9I6WnyubDbFO/+A/RROxIbXcwryTsc=
|
||||
github.com/emiago/sipgo v0.28.0 h1:wW9W+p89ldLbKOhXhj9BHo6U39vuWdUc0WVZ+E3rk6Y=
|
||||
github.com/emiago/sipgo v0.28.0/go.mod h1:ZQ/tl5t+3assyOjiKw/AInPkcawBJ2Or+d5buztOZsc=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
|
52
pkg/manscdp/catalog.go
Normal file
52
pkg/manscdp/catalog.go
Normal file
@ -0,0 +1,52 @@
|
||||
package manscdp
|
||||
|
||||
import "encoding/xml"
|
||||
|
||||
type CatalogReq struct {
|
||||
XMLName xml.Name `xml:"Query"`
|
||||
CmdType string `xml:"CmdType"`
|
||||
SN string `xml:"SN"`
|
||||
DeviceID string `xml:"DeviceID"`
|
||||
}
|
||||
|
||||
type CatalogResp struct {
|
||||
XMLName xml.Name `xml:"Response"`
|
||||
CmdType string `xml:"CmdType"`
|
||||
SumNum string `xml:"SumNum"`
|
||||
DeviceList *CateLogDeviceList `xml:"DeviceList"`
|
||||
SN string `xml:"SN"`
|
||||
DeviceID string `xml:"DeviceID"`
|
||||
}
|
||||
|
||||
type CateLogDeviceList struct {
|
||||
XMLName xml.Name `xml:"DeviceList"`
|
||||
Num string `xml:"Num,attr"`
|
||||
Item []CateLogDevice `xml:"Item"`
|
||||
}
|
||||
|
||||
type CateLogDevice struct {
|
||||
XMLName xml.Name `xml:"Item"`
|
||||
Name string `xml:"Name"`
|
||||
Manufacturer string `xml:"Manufacturer"`
|
||||
Model string `xml:"Model"`
|
||||
Owner string `xml:"Owner"`
|
||||
Block string `xml:"Block"`
|
||||
Address string `xml:"Address"`
|
||||
Parental string `xml:"Parental"`
|
||||
SafetyWay string `xml:"SafetyWay"`
|
||||
RegisterWay string `xml:"RegisterWay"`
|
||||
CertNum string `xml:"CertNum"`
|
||||
Certifiable string `xml:"Certifiable"`
|
||||
ErrCode string `xml:"ErrCode"`
|
||||
EndTime string `xml:"EndTime"`
|
||||
Secrecy string `xml:"Secrecy"`
|
||||
Port string `xml:"Port"`
|
||||
Password string `xml:"Password"`
|
||||
Status string `xml:"Status"`
|
||||
Longitude string `xml:"Longitude"`
|
||||
Latitude string `xml:"Latitude"`
|
||||
DeviceID string `xml:"DeviceID"`
|
||||
CivilCode string `xml:"CivilCode"`
|
||||
ParentID string `xml:"ParentID"`
|
||||
IPAddress string `xml:"IPAddress"`
|
||||
}
|
@ -2,7 +2,10 @@ package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"git.skcks.cn/Shikong/go-gb28181/pkg/manscdp"
|
||||
"git.skcks.cn/Shikong/go-gb28181/pkg/utils"
|
||||
"github.com/emiago/sipgo"
|
||||
"github.com/emiago/sipgo/sip"
|
||||
"github.com/icholy/digest"
|
||||
@ -130,6 +133,72 @@ func TestClient(t *testing.T) {
|
||||
<-quit
|
||||
}
|
||||
|
||||
func TestCatalog(t *testing.T) {
|
||||
ua, _ := sipgo.NewUA(
|
||||
sipgo.WithUserAgent("44050100002000000002"),
|
||||
sipgo.WithUserAgentHostname("10.10.10.20:5099"))
|
||||
|
||||
client, _ := sipgo.NewClient(ua,
|
||||
sipgo.WithClientHostname("10.10.10.20"),
|
||||
sipgo.WithClientPort(5099))
|
||||
|
||||
resp := new(manscdp.CatalogResp)
|
||||
resp.XMLName = xml.Name{Local: "Response"}
|
||||
resp.DeviceID = "44050100002000000002"
|
||||
resp.CmdType = "Catalog"
|
||||
resp.SumNum = "1"
|
||||
resp.DeviceList = new(manscdp.CateLogDeviceList)
|
||||
resp.DeviceList.XMLName = xml.Name{Local: "DeviceList"}
|
||||
resp.DeviceList.Num = "1"
|
||||
resp.DeviceList.Item = make([]manscdp.CateLogDevice, 1)
|
||||
resp.DeviceList.Item[0].DeviceID = "44050100002000000002"
|
||||
resp.DeviceList.Item[0].Name = "设备名称"
|
||||
resp.DeviceList.Item[0].Manufacturer = "设备厂商"
|
||||
resp.DeviceList.Item[0].ErrCode = "0"
|
||||
resp.DeviceList.Item[0].EndTime = "2022-12-31'T'23:59:59"
|
||||
resp.DeviceList.Item[0].Port = fmt.Sprintf("%d", 5099)
|
||||
|
||||
resp.SN = "90000"
|
||||
|
||||
marshal, _ := utils.XMLMarshal(resp, "gb2312")
|
||||
t.Logf("回复查询指令: %s\n%+v\n", "Catalog", resp)
|
||||
|
||||
target := sip.Uri{
|
||||
User: "44050100002000000003",
|
||||
Host: "10.10.10.20",
|
||||
Port: 5060,
|
||||
Headers: sip.NewParams(),
|
||||
}
|
||||
|
||||
time.Sleep(time.Second * 1)
|
||||
//uri := sip.Uri{User: "44050100002000000002", Host: "10.10.10.20", Port: 5099}
|
||||
nReq := sip.NewRequest(sip.MESSAGE, target)
|
||||
nReq.SetTransport("UDP")
|
||||
//to := sip.NewHeader("To", req.GetHeader("From").Value())
|
||||
//from := sip.NewHeader("From", req.GetHeader("To").Value())
|
||||
//nReq.AppendHeader(to)
|
||||
//nReq.AppendHeader(from)
|
||||
//nReq.AppendHeader(req.GetHeader("Call-ID"))
|
||||
nReq.AppendHeader(sip.NewHeader("Content-Type", "Application/MANSCDP+xml"))
|
||||
|
||||
nReq.SetBody(marshal)
|
||||
err := sipgo.ClientRequestBuild(client, nReq)
|
||||
//if err != nil {
|
||||
// logger.Error().Err(err)
|
||||
//}
|
||||
|
||||
t.Logf("向服务器发送查询指令: %s\n%+v\n", "Catalog", nReq)
|
||||
|
||||
client.TransactionLayer()
|
||||
_, err = client.TransactionRequest(context.Background(), nReq)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
_ = client.Close()
|
||||
t.Log("向服务器发送查询指令完成")
|
||||
}
|
||||
|
||||
func getResponse(tx sip.ClientTransaction) (*sip.Response, error) {
|
||||
select {
|
||||
case <-tx.Done():
|
||||
|
Loading…
Reference in New Issue
Block a user