fiorix / go-smpp

SMPP 3.4 Protocol for the Go programming language
MIT License
218 stars 135 forks source link

How to make valid NewDeliverSM? Any example? #73

Open mateuszbbb opened 6 years ago

mateuszbbb commented 6 years ago

I'm trying to send DLR using NewDeliverSM, but with no success. Message is sent, but not recognized as DLR

I tried with: p := pdu.NewDeliverSM() p.TLVFields().Set(pdutlv.TagReceiptedMessageID, pdutlv.CString("1234")) p.TLVFields().Set(pdutlv.TagMessageStateOption, 2) f := p.Fields() f.Set(pdufield.SourceAddr, m.Fields()[pdufield.SourceAddr]) f.Set(pdufield.DestinationAddr, m.Fields()[pdufield.DestinationAddr]) f.Set(pdufield.ESMClass, 4) f.Set(pdufield.ServiceType, m.Fields()[pdufield.ServiceType]) f.Set(pdufield.ProtocolID, 0) p.Header().Status = 0 p.Header().Seq = m.Header().Seq + 1 f.Set(pdufield.ShortMessage, pdutext.Latin1("id:1234 sub:001 dlvrd:001 submit date:180625012100 done date:180625012101 stat:DELIVRD err:000 text:"))

where f are fields from original SubmitSM, "1234" message @#id

What I'm doing wrong here? Do I need to encode values like pdufield.ESMClass = 4 to other formats?

Any working example will be appreciated

fiorix commented 6 years ago

You'll likely need to take captures and compare with a working client. I cannot help much on this one.

mateuszbbb commented 6 years ago

I think that I have found error, I generate DeliverSM with following code:

        p := pdu.NewDeliverSM()
        p.Header().Status = 0
        p.Header().Seq = m.Header().Seq + 1
        f := p.Fields()
        f.Set(pdufield.DestAddrTON, m.Fields()[pdufield.SourceAddrTON])
        f.Set(pdufield.DestAddrNPI, m.Fields()[pdufield.SourceAddrNPI])
        f.Set(pdufield.DestinationAddr, m.Fields()[pdufield.SourceAddr])
        f.Set(pdufield.SourceAddr, m.Fields()[pdufield.DestinationAddr])
        f.Set(pdufield.SourceAddrTON, m.Fields()[pdufield.DestAddrTON])
        f.Set(pdufield.SourceAddrNPI, m.Fields()[pdufield.DestAddrNPI])
        f.Set(pdufield.ESMClass, []byte{0x04})
        f.Set(pdufield.ProtocolID, []byte{0x00})
        f.Set(pdufield.PriorityFlag, []byte{0x00})
        f.Set(pdufield.ScheduleDeliveryTime, []byte{0x00})
        f.Set(pdufield.ValidityPeriod, []byte{0x00})
        f.Set(pdufield.RegisteredDelivery, []byte{0x00})
        f.Set(pdufield.ReplaceIfPresentFlag, []byte{0x00})
        f.Set(pdufield.DataCoding, m.Fields()[pdufield.DataCoding])
        f.Set(pdufield.SMDefaultMsgID, []byte{0x00})
        f.Set(pdufield.ServiceType, m.Fields()[pdufield.ServiceType])
        f.Set(pdufield.ShortMessage, pdutext.Raw("id:12345678901234567890 submit date:201806251516 done date:201806251517 stat:DELIVRD err:002"))
        p.TLVFields().Set(pdutlv.TagMessageStateOption, []byte{2})
        p.TLVFields().Set(pdutlv.TagReceiptedMessageID, pdutlv.CString("12345678901234567890"))

In Wireshark capture I see that output is almost identical with proper DeliverSM sent by working SMSC

The problem is that pdufield.ShortMessage, pdutext.Raw("") generated by your package has proper length field, but ShortMessage is prefixed by zero byte (0x00), that corrupts further data.

Output is:

0010   00 02 01 35 30 31 31 32 31 31 38 30 00 05 00 53   ...101121180...S
0020   45 4e 44 45 52 00 04 00 00 00 00 00 00 00 00 5c   ENDER..........\
0030   00 69 64 3a 31 32 33 34 35 36 37 38 39 30 31 32   .id:123456789012
0040   33 34 35 36 37 38 39 30 20 73 75 62 6d 69 74 20   34567890 submit 
0050   64 61 74 65 3a 32 30 31 38 30 36 32 35 31 35 31   date:20180625151
0060   36 20 64 6f 6e 65 20 64 61 74 65 3a 32 30 31 38   6 done date:2018
0070   30 36 32 35 31 35 31 37 20 73 74 61 74 3a 44 45   06251517 stat:DE
0080   4c 49 56 52 44 20 65 72 72 3a 30 30 32 00 1e 00   LIVRD err:002...
0090   15 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35   .123456789012345
00a0   36 37 38 39 30 00                                 67890.

that's the byte with offset 0030, just before id:12345...

Without this zero byte it seems that will be OK and client will accept it

Can you please advise how to patch your code to get rid of this zero byte? I'm not proficient binary protocol hacker

I can even pay you some sum for your time since I'm doing commercially a part of middleware and need to get it working ASAP

mateuszbbb commented 6 years ago

Here is how Wireshark see this part of message, please observe that message length byte is OK. Message is just prefixed with zero byte, so the last byte is cut (thats digit 2 from "err:002" part of message)

Here you go with screenshot: https://drive.google.com/open?id=1MowVjmbhMY-B1Vr3PsSs8QzBTmb0JQCX

mateuszbbb commented 6 years ago

As said I'm ready to pay for your time, maybe this one will help: https://www.freelancer.pl/projects/linux/develop-fix-small-fragment-golang/#/details

fiorix commented 6 years ago

Here's the layout of DeliverSM: https://github.com/fiorix/go-smpp/blob/master/smpp/pdu/types.go#L293

The immediate field before ShortMessage is GSMUserData, which was added about a year ago by @nezorflame in 24f8c599fed71be1a83b304ec861d4230fd3df94.

Try commenting it out and re-run your test?

madcatz0r commented 5 years ago

@fiorix pdufield.UDHLength makes excess 0x00 byte not GSMUserData.

robertmircea commented 4 years ago

I've encountered the same problem: pdu.NewDeliverSM() does not produce a valid smpp pdu and the message is unparsable by other smpp clients which are known to be working with real SMSC. The culprits are pdufield.UDHLength and pdufield.GSMUserData which should not belong to pdufield.List. These fields are not part of DeliverSM pdu according to spec. If I eliminate them then everything works as expected.

nezorflame commented 4 years ago

To be honest, I don't remember the specifics on why have we added it this way since it was a while ago, but if you were to refactor and fix it, I'd gladly review this.


Best regards, Ilya Danilkin

С уважением, Илья Данилкин

сб, 11 янв. 2020 г., 16:08 Robert Mircea notifications@github.com:

I've encountered the same problem: pdu.NewDeliverSM() does not produce a valid smpp pdu and the message is unparsable by other smpp clients which are known to be working with real SMSC. The culprits are pdufield.UDHLength and pdufield.GSMUserData which should not belong to pdufield.List. These fields are not part of DeliverSM pdu according to spec. If I eliminate them then everything works as expected.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/fiorix/go-smpp/issues/73?email_source=notifications&email_token=AA5ZZTTYYMV3HVXLINXDWUDQ5HADJA5CNFSM4FGVNOZ2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEIWBTHY#issuecomment-573315487, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA5ZZTXMWNWTVQXFVENKON3Q5HADJANCNFSM4FGVNOZQ .

Munmendu commented 4 years ago

Thanks robert. It worked after commenting both UDHLength and GSMUserData . May I know,why still the fix are not merged into main branch ?

AShabana commented 3 years ago

@Munmendu , This also worked with us

The length of the message calculated without the null termination character the correction must be length + 1