go-gb28181/test/client_test.go

210 lines
5.1 KiB
Go
Raw Normal View History

2025-01-23 18:51:43 +08:00
package test
import (
"context"
"encoding/xml"
2025-01-23 18:51:43 +08:00
"fmt"
"git.skcks.cn/Shikong/go-gb28181/pkg/manscdp"
"git.skcks.cn/Shikong/go-gb28181/pkg/utils"
2025-01-23 18:51:43 +08:00
"github.com/emiago/sipgo"
"github.com/emiago/sipgo/sip"
"github.com/icholy/digest"
"os"
"os/signal"
"testing"
"time"
)
func TestClient(t *testing.T) {
sip.SIPDebug = true
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
ua, _ := sipgo.NewUA(
2025-01-24 03:35:32 +08:00
sipgo.WithUserAgent("44050100002000000002"),
sipgo.WithUserAgentHostname("10.10.10.20:5099"))
2025-01-23 18:51:43 +08:00
srv, _ := sipgo.NewServer(ua) // Creating server handle
client, _ := sipgo.NewClient(ua,
sipgo.WithClientPort(5099),
sipgo.WithClientHostname("10.10.10.20"))
target := sip.Uri{
User: "44050100002000000003",
Host: "10.10.10.20",
Port: 5060,
Headers: sip.NewParams(),
}
uri := sip.Uri{User: "44050100002000000002", Host: "10.10.10.20", Port: 5099}
req := sip.NewRequest(sip.REGISTER, target)
req.AppendHeader(sip.NewHeader("X-GB-Ver", "2.0"))
req.AppendHeader(sip.NewHeader("Contact", uri.String()))
req.AppendHeader(sip.NewHeader("Expires", "3600"))
//req.Contact = uasContact
err := sipgo.ClientRequestBuild(client, req)
if err != nil {
t.Fatal(err)
}
quit := make(chan os.Signal)
go func() {
err = srv.ListenAndServe(ctx, "udp", ":5099")
if err != nil {
t.Fatal(err)
}
}()
go func() {
defer func() {
cancel()
quit <- os.Interrupt
}()
//for {
select {
case <-ctx.Done():
break
default:
tx, err := client.TransactionRequest(ctx, req)
if err != nil {
t.Fatal(err)
}
resp, err := getResponse(tx)
tx.Terminate()
headers := resp.Headers()
for _, h := range headers {
t.Log(h.Name(), "=>", h.Value())
}
t.Log(resp.String())
if resp.StatusCode == 401 {
wwwAuth := resp.GetHeader("WWW-Authenticate")
chal, err := digest.ParseChallenge(wwwAuth.Value())
if err != nil {
t.Fatal(err, "Fail to parse challenge")
}
// Reply with digest
cred, _ := digest.Digest(chal, digest.Options{
Method: req.Method.String(),
Username: "44050100002000000002",
URI: target.String(),
Password: "123456",
})
newReq := req.Clone()
newReq.RemoveHeader("Via") // Must be regenerated by tranport layer
newReq.AppendHeader(sip.NewHeader("Authorization", cred.String()))
ctx := context.Background()
tx, err := client.TransactionRequest(ctx, newReq, sipgo.ClientRequestAddVia)
if err != nil {
t.Fatal("Fail to create transaction")
}
resp, err = getResponse(tx)
tx.Terminate()
if err != nil {
t.Fatal("Fail to get response")
}
if resp.StatusCode != 403 {
headers := resp.Headers()
for _, h := range headers {
t.Log(h.Name(), "=>", h.Value())
}
tx.Done()
//break
}
t.Log(resp.String())
}
}
//}
}()
signal.Notify(quit, os.Interrupt)
<-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("向服务器发送查询指令完成")
}
2025-01-23 18:51:43 +08:00
func getResponse(tx sip.ClientTransaction) (*sip.Response, error) {
select {
case <-tx.Done():
return nil, fmt.Errorf("transaction died")
case res := <-tx.Responses():
return res, nil
}
}