AdhamAwadhi / JamaaSMPP

Jamaa SMPP Client is a .NET implementation of the SMPP protocol that focuses on providing an easy-to-use and robust SMPP client library for .NET developers. This project is intended to be used by developers who want to integrate SMS functionalities in their applications as well as students who are learning the SMPP protocol.
https://github.com/AdhamAwadhi/JamaaSMPP/wiki
Other
43 stars 36 forks source link

UserMessageReference length #25

Open impworks opened 5 years ago

impworks commented 5 years ago

Hello Adham,

I came across a strange behaviour in JamaaSMPP. According to the SMPP 3.4 spec, the user_message_reference TLV can only be 2 bytes long: http://docs.nimta.com/SMPP_v3_4_Issue1_2.pdf

image

However, JamaaSMPP allows a string of arbitrary length to be passed and also adds an extra zero byte at the end: https://github.com/AdhamAwadhi/JamaaSMPP/blob/master/JamaaTech.Smpp.Net.Client/TextMessage.cs#L70

My provider does not accept such a message and throws the ESME_RINVPARLEN error. Sending a message using only a single byte ID works as expected, but this is a hack and cannot be deployed to production.

Why does it work like that? Is there any fix or a workaround?

sebafaro commented 5 years ago

Hey, i have the same issue. Any way to fix it?

Best Regads

impworks commented 5 years ago

@sebafaro unfortunately I found no clean workaround, but you have two options:

  1. Fork and patch JamaaSMPP yourself
  2. Use a different provider

Some providers accept a variable-length user_message_reference TLV, even if it violates the standard.

sebafaro commented 5 years ago

@sebafaro unfortunately I found no clean workaround, but you have two options:

  1. Fork and patch JamaaSMPP yourself
  2. Use a different provider

Some providers accept a variable-length user_message_reference TLV, even if it violates the standard.

Thanks for your quick response. The 2 is not an option, we only have that provider. And for the 1 i don't have enough skill xD

I need to obtain a response from the provider when the message is sent, so i can save it and check if was any failure. If i use the ReceiptedMessageId, i receive the id. Can i assume that if that id is != null the message was sent?

Sorry i'm a total newbie on SMPP.

impworks commented 5 years ago

@sebafaro As for delivery, the SmppClient class provides two events: MessageSent and MessageDelivered. You should subscribe to those events and handle them.

There are, however, two tricky parts to these events that you should keep in mind to avoid a rare but very unpleasant bug.

Each SMPP message has two IDs: one assigned by you (UserMessageReference) and the other assigned by the provider (ReceiptedMessageId). The first problem is that the MessageSent event args contain both your and the provider's IDs, but the MessageDelivered only contain the provider's ID.

So, to ensure a message has been delivered, you first have to find out it's ID from the MessageSent handler, and then receive a MessageDelivered event with that ID. But the second problem this is that the MessageDelivered event for a message can actually be fired before MessageSent.

Basically, you send a message and give it an ID of "A". Then, you get the notification Message "B" delivered, but you have no idea what "B" is. And only then, at some later time, the provider reports that Your message "A" is registered as "B".

It's frustrating, but actually easy to work around by just storing the delivery facts somewhere until both IDs are known.