Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Long message multi-part tracking #76

Merged
merged 1 commit into from
Aug 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions smpp/transmitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,14 +327,16 @@ func (t *Transmitter) Submit(sm *ShortMessage) (*ShortMessage, error) {
// SubmitLongMsg sends a long message (more than 140 bytes)
// and returns and updates the given sm with the response status.
// It returns the same sm object.
func (t *Transmitter) SubmitLongMsg(sm *ShortMessage) (*ShortMessage, error) {
func (t *Transmitter) SubmitLongMsg(sm *ShortMessage) ([]ShortMessage, error) {
maxLen := 133 // 140-7 (UDH with 2 byte reference number)
if sm.Text.Type() == pdutext.UCS2Type {
maxLen = 132 // to avoid a character being split between payloads
}
rawMsg := sm.Text.Encode()
countParts := int((len(rawMsg)-1)/maxLen) + 1

parts := make([]ShortMessage, 0, countParts)

t.rMutex.Lock()
rn := uint16(t.r.Intn(0xFFFF))
t.rMutex.Unlock()
Expand Down Expand Up @@ -380,19 +382,20 @@ func (t *Transmitter) SubmitLongMsg(sm *ShortMessage) (*ShortMessage, error) {
sm.resp.p = resp.PDU
sm.resp.Unlock()
if resp.PDU == nil {
return nil, fmt.Errorf("unexpected empty PDU")
return parts, fmt.Errorf("unexpected empty PDU")
}
if id := resp.PDU.Header().ID; id != pdu.SubmitSMRespID {
return sm, fmt.Errorf("unexpected PDU ID: %s", id)
return parts, fmt.Errorf("unexpected PDU ID: %s", id)
}
if s := resp.PDU.Header().Status; s != 0 {
return sm, s
return parts, s
}
if resp.Err != nil {
return sm, resp.Err
return parts, resp.Err
}
parts = append(parts, *sm)
}
return sm, nil
return parts, nil
}

func (t *Transmitter) submitMsg(sm *ShortMessage, p pdu.Body, dataCoding uint8) (*ShortMessage, error) {
Expand Down
49 changes: 32 additions & 17 deletions smpp/transmitter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/fiorix/go-smpp/smpp/pdu/pdufield"
"github.com/fiorix/go-smpp/smpp/pdu/pdutext"
"github.com/fiorix/go-smpp/smpp/smpptest"
"fmt"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Run gofmt in this file? Move "fmt" with the rest of stdlib imports

)

func TestShortMessage(t *testing.T) {
Expand Down Expand Up @@ -121,12 +122,14 @@ func TestShortMessageWindowSize(t *testing.T) {

func TestLongMessage(t *testing.T) {
s := smpptest.NewUnstartedServer()
count := 0
s.Handler = func(c smpptest.Conn, p pdu.Body) {
switch p.Header().ID {
case pdu.SubmitSMID:
r := pdu.NewSubmitSMResp()
r.Header().Seq = p.Header().Seq
r.Fields().Set(pdufield.MessageID, "foobar")
r.Fields().Set(pdufield.MessageID, fmt.Sprintf("foobar%d", count))
count++
c.Write(r)
default:
smpptest.EchoHandler(c, p)
Expand All @@ -146,7 +149,7 @@ func TestLongMessage(t *testing.T) {
default:
t.Fatal(conn.Error())
}
sm, err := tx.SubmitLongMsg(&ShortMessage{
parts, err := tx.SubmitLongMsg(&ShortMessage{
Src: "root",
Dst: "foobar",
Text: pdutext.Raw("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam consequat nisl enim, vel finibus neque aliquet sit amet. Interdum et malesuada fames ac ante ipsum primis in faucibus."),
Expand All @@ -156,25 +159,32 @@ func TestLongMessage(t *testing.T) {
if err != nil {
t.Fatal(err)
}
msgid := sm.RespID()
if msgid == "" {
t.Fatalf("pdu does not contain msgid: %#v", sm.Resp())
if len(parts) != 2 {
t.Fatalf("expected %d responses, but received %d", 2, len(parts))
}
if msgid != "foobar" {
t.Fatalf("unexpected msgid: want foobar, have %q", msgid)
for index, sm := range parts {
msgid := sm.RespID()
if msgid == "" {
t.Fatalf("pdu does not contain msgid: %#v", sm.Resp())
}
if msgid != fmt.Sprintf("foobar%d", index) {
t.Fatalf("unexpected msgid: want foobar%d, have %q", index, msgid)
}
}
}

func TestLongMessageAsUCS2(t *testing.T) {
s := smpptest.NewUnstartedServer()
var receivedMsg string
shortMsg := "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam consequat nisl enim, vel finibus neque aliquet sit amet. Interdum et malesuada fames ac ante ipsum primis in faucibus. ✓"
count := 0
s.Handler = func(c smpptest.Conn, p pdu.Body) {
switch p.Header().ID {
case pdu.SubmitSMID:
r := pdu.NewSubmitSMResp()
r.Header().Seq = p.Header().Seq
r.Fields().Set(pdufield.MessageID, "foobar")
r.Fields().Set(pdufield.MessageID, fmt.Sprintf("foobar%d", count))
count++
smByts := p.Fields()[pdufield.ShortMessage].Bytes()
switch pdutext.DataCoding(p.Fields()[pdufield.DataCoding].Raw().(uint8)) {
case pdutext.Latin1Type:
Expand Down Expand Up @@ -203,7 +213,7 @@ func TestLongMessageAsUCS2(t *testing.T) {
default:
t.Fatal(conn.Error())
}
sm, err := tx.SubmitLongMsg(&ShortMessage{
parts, err := tx.SubmitLongMsg(&ShortMessage{
Src: "root",
Dst: "foobar",
Text: pdutext.UCS2(shortMsg),
Expand All @@ -213,17 +223,22 @@ func TestLongMessageAsUCS2(t *testing.T) {
if err != nil {
t.Fatal(err)
}
msgid := sm.RespID()
if msgid == "" {
t.Fatalf("pdu does not contain msgid: %#v", sm.Resp())
if len(parts) != 3 {
t.Fatalf("expected %d responses, but received %d", 3, len(parts))
}
for index, sm := range parts {
msgid := sm.RespID()
if msgid == "" {
t.Fatalf("pdu does not contain msgid: %#v", sm.Resp())
}

if receivedMsg != shortMsg {
t.Fatalf("receivedMsg: %v, does not match shortMsg: %v", receivedMsg, shortMsg)
}
if receivedMsg != shortMsg {
t.Fatalf("receivedMsg: %v, does not match shortMsg: %v", receivedMsg, shortMsg)
}

if msgid != "foobar" {
t.Fatalf("unexpected msgid: want foobar, have %q", msgid)
if msgid != fmt.Sprintf("foobar%d", index) {
t.Fatalf("unexpected msgid: want foobar%d, have %q", index, msgid)
}
}
}

Expand Down