feat: complete cmpp platform phases 0-5
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
package cmppadapter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
cmpp "github.com/bigwhite/gocmpp"
|
||||
cmpputils "github.com/bigwhite/gocmpp/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
spikeUser = "900001"
|
||||
spikePassword = "888888"
|
||||
)
|
||||
|
||||
func TestGocmppConnectSubmitAndActiveTest(t *testing.T) {
|
||||
addr := reserveTCPAddr(t)
|
||||
handlers := []cmpp.Handler{
|
||||
cmpp.HandlerFunc(handleSpikeLogin),
|
||||
cmpp.HandlerFunc(handleSpikeSubmit),
|
||||
}
|
||||
|
||||
go func() {
|
||||
err := cmpp.ListenAndServe(addr, cmpp.V30, 2*time.Second, 3, nil, handlers...)
|
||||
if err != nil {
|
||||
log.Printf("gocmpp spike server stopped: %v", err)
|
||||
}
|
||||
}()
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
|
||||
client := cmpp.NewClient(cmpp.V30)
|
||||
defer client.Disconnect()
|
||||
|
||||
if err := client.Connect(addr, spikeUser, spikePassword, 2*time.Second); err != nil {
|
||||
t.Fatalf("connect gocmpp server: %v", err)
|
||||
}
|
||||
|
||||
content, err := cmpputils.Utf8ToUcs2("测试gocmpp submit")
|
||||
if err != nil {
|
||||
t.Fatalf("encode submit content: %v", err)
|
||||
}
|
||||
|
||||
_, err = client.SendReqPkt(&cmpp.Cmpp3SubmitReqPkt{
|
||||
PkTotal: 1,
|
||||
PkNumber: 1,
|
||||
RegisteredDelivery: 1,
|
||||
MsgLevel: 1,
|
||||
ServiceId: "test",
|
||||
FeeUserType: 2,
|
||||
FeeTerminalId: "13500002696",
|
||||
FeeTerminalType: 0,
|
||||
MsgFmt: 8,
|
||||
MsgSrc: spikeUser,
|
||||
FeeType: "02",
|
||||
FeeCode: "10",
|
||||
ValidTime: "151105131555101+",
|
||||
AtTime: "",
|
||||
SrcId: spikeUser,
|
||||
DestUsrTl: 1,
|
||||
DestTerminalId: []string{"13500002696"},
|
||||
DestTerminalType: 0,
|
||||
MsgLength: uint8(len(content)),
|
||||
MsgContent: content,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("send submit: %v", err)
|
||||
}
|
||||
|
||||
submitRsp := recvUntil[*cmpp.Cmpp3SubmitRspPkt](t, client, 2*time.Second)
|
||||
if submitRsp.Result != 0 {
|
||||
t.Fatalf("unexpected submit result: %d", submitRsp.Result)
|
||||
}
|
||||
if submitRsp.MsgId == 0 {
|
||||
t.Fatal("expected gateway msg id")
|
||||
}
|
||||
|
||||
_, err = client.SendReqPkt(&cmpp.CmppActiveTestReqPkt{})
|
||||
if err != nil {
|
||||
t.Fatalf("send active test: %v", err)
|
||||
}
|
||||
_ = recvUntil[*cmpp.CmppActiveTestRspPkt](t, client, 2*time.Second)
|
||||
}
|
||||
|
||||
func TestGocmppDeliverReceiptPackAndUnpack(t *testing.T) {
|
||||
receipt := &cmpp.CmppReceiptPkt{
|
||||
MsgId: 12878564852733378560,
|
||||
Stat: "DELIVRD",
|
||||
SubmitTime: "2607010900",
|
||||
DoneTime: "2607010901",
|
||||
DestTerminalId: "13500002696",
|
||||
SmscSequence: 42,
|
||||
}
|
||||
receiptBytes, err := receipt.Pack()
|
||||
if err != nil {
|
||||
t.Fatalf("pack receipt: %v", err)
|
||||
}
|
||||
|
||||
deliver := &cmpp.Cmpp3DeliverReqPkt{
|
||||
MsgId: 12878564852733378560,
|
||||
DestId: "106900000000",
|
||||
ServiceId: "test",
|
||||
TpPid: 0,
|
||||
TpUdhi: 0,
|
||||
MsgFmt: 0,
|
||||
SrcTerminalId: "13500002696",
|
||||
SrcTerminalType: 0,
|
||||
RegisterDelivery: 1,
|
||||
MsgLength: uint8(cmpp.CmppReceiptPktLen),
|
||||
MsgContent: string(receiptBytes),
|
||||
}
|
||||
|
||||
data, err := deliver.Pack(1001)
|
||||
if err != nil {
|
||||
t.Fatalf("pack deliver receipt: %v", err)
|
||||
}
|
||||
|
||||
var unpacked cmpp.Cmpp3DeliverReqPkt
|
||||
if err := unpacked.Unpack(data[8:]); err != nil {
|
||||
t.Fatalf("unpack deliver receipt: %v", err)
|
||||
}
|
||||
|
||||
var gotReceipt cmpp.CmppReceiptPkt
|
||||
if err := gotReceipt.Unpack([]byte(unpacked.MsgContent)); err != nil {
|
||||
t.Fatalf("unpack receipt content: %v", err)
|
||||
}
|
||||
if gotReceipt.Stat != "DELIVRD" || gotReceipt.SmscSequence != 42 {
|
||||
t.Fatalf("unexpected receipt payload: %+v", &gotReceipt)
|
||||
}
|
||||
}
|
||||
|
||||
func reserveTCPAddr(t *testing.T) string {
|
||||
t.Helper()
|
||||
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatalf("reserve tcp addr: %v", err)
|
||||
}
|
||||
addr := listener.Addr().String()
|
||||
if err := listener.Close(); err != nil {
|
||||
t.Fatalf("close reserved listener: %v", err)
|
||||
}
|
||||
return addr
|
||||
}
|
||||
|
||||
func recvUntil[T any](t *testing.T, client *cmpp.Client, timeout time.Duration) T {
|
||||
t.Helper()
|
||||
|
||||
deadline := time.Now().Add(timeout)
|
||||
for time.Now().Before(deadline) {
|
||||
packet, err := client.RecvAndUnpackPkt(200 * time.Millisecond)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if typed, ok := packet.(T); ok {
|
||||
return typed
|
||||
}
|
||||
}
|
||||
|
||||
var zero T
|
||||
t.Fatalf("timed out waiting for %T", zero)
|
||||
return zero
|
||||
}
|
||||
|
||||
func handleSpikeLogin(response *cmpp.Response, packet *cmpp.Packet, logger *log.Logger) (bool, error) {
|
||||
req, ok := packet.Packer.(*cmpp.CmppConnReqPkt)
|
||||
if !ok {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
resp := response.Packer.(*cmpp.Cmpp3ConnRspPkt)
|
||||
resp.Version = 0x30
|
||||
|
||||
if req.SrcAddr != cmpputils.OctetString(spikeUser, 6) {
|
||||
resp.Status = uint32(cmpp.ErrnoConnInvalidSrcAddr)
|
||||
return false, cmpp.ConnRspStatusErrMap[cmpp.ErrnoConnInvalidSrcAddr]
|
||||
}
|
||||
|
||||
authSrc := md5.Sum(bytes.Join([][]byte{
|
||||
[]byte(cmpputils.OctetString(spikeUser, 6)),
|
||||
make([]byte, 9),
|
||||
[]byte(spikePassword),
|
||||
[]byte(cmpputils.TimeStamp2Str(req.Timestamp)),
|
||||
}, nil))
|
||||
|
||||
if req.AuthSrc != string(authSrc[:]) {
|
||||
resp.Status = uint32(cmpp.ErrnoConnAuthFailed)
|
||||
return false, cmpp.ConnRspStatusErrMap[cmpp.ErrnoConnAuthFailed]
|
||||
}
|
||||
|
||||
authIsmg := md5.Sum(bytes.Join([][]byte{{byte(resp.Status)}, authSrc[:], []byte(spikePassword)}, nil))
|
||||
resp.AuthIsmg = string(authIsmg[:])
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func handleSpikeSubmit(response *cmpp.Response, packet *cmpp.Packet, logger *log.Logger) (bool, error) {
|
||||
req, ok := packet.Packer.(*cmpp.Cmpp3SubmitReqPkt)
|
||||
if !ok {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if req.DestUsrTl == 0 || len(req.DestTerminalId) == 0 {
|
||||
return false, fmt.Errorf("missing submit destination")
|
||||
}
|
||||
|
||||
resp := response.Packer.(*cmpp.Cmpp3SubmitRspPkt)
|
||||
resp.MsgId = 12878564852733378560
|
||||
resp.Result = 0
|
||||
return false, nil
|
||||
}
|
||||
Reference in New Issue
Block a user