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" "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( sipgo.WithUserAgent("44050100002000000002"), sipgo.WithUserAgentHostname("10.10.10.20:5099")) 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("向服务器发送查询指令完成") } 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 } }