Hi Oran
Please help me with this:
I'm getting a Connection Fatal exception in receiver thread (RX) when SMSC sent sms (MO) with blank message text (I mean without text on message data).
After that I can't receive any more MO messages until restart connection.
This is a copy of logger:
java.lang.ArrayIndexOutOfBoundsException: 1
at ie.omk.smpp.util.SMPPIO.bytesToInt(Unknown Source)
at ie.omk.smpp.message.tlv.TLVTable.parseAllOpts(Unknown Source)
at ie.omk.smpp.message.tlv.TLVTable.getLength(Unknown Source)
at ie.omk.smpp.message.SMPPPacket.getLength(Unknown Source)
at ie.omk.smpp.Connection.readNextPacketInternal(Unknown Source)
at ie.omk.smpp.Connection.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Any idea of what's wrong?
Thank you in advance for your help.
fboesche.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Oran,
I going to talk with SMSC technician to see if they can fix the blank sms bug you found! from their side.
I'm not sure, but I remember that they said they going to implement TLVTable on their SMSC applications server. I going to ask also about it.
Questions:
When you say that TLVTable parsing exception occurs only when I call some method that calls its parseAllOptions method means that it's possible that I have included some code on my application for use TLVTables parsing?
Do you think that I can fix the bug from my side making some code changes just for this SMSC connection? Maybe this is the easy way instead of involving too many people from SMSC side.
Thanks again.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
On question 1: not necessarily. the TLVTable in 0.3.x lazy-parses for inbound packets. That is, it doesn't actually parse the TLVs out of the bytes until something is done on the TLVTable. There are various ways in which this might happen - a simple example is calling SMPPPacket.getLength. Since it needs to know the length of the TLVTable, it calls TLVTable.getLength which then causes parseAllOpts to be invoked.
On your second question: you could probably modify the implementation of TLVTable to be resilient to invalid bytes. For example, you could modify parseAllOpts to not throw an exception if it cannot parse out the TLVTable, it could simply ignore the invalid data. That approach would work in this specific case but it would prevent you from being able to use TLVs in deliver_sm packets.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ok, I understand that.
Trying to fix it in the right way I'm going to talk with the SMSC technician and only if they can't or don't want to do it, I will go to modify the code.
Oran, kindly appreciated your help. I will like to let you know how finally I can fix it.
Regards,
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Not much info but my best guess is that the smppapi has read the command length of what I assume is a deliver_sm packet. It has parsed all the mandatory parameters but sees that there are still bytes available which implies there are TLVs. It then tries to parse the TLV table but in actual fact the bytes are not available, hence the exception.
If possible, can you capture the bytes of the deliver_sm packet and either email them to me (at my sourceforge address) or grab a hex dump of the deliver_sm packet and post it here so that I can analyse the packet to see if this is something wrong with the smppapi parsing mechanism. What version of smppapi is this happening with?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you Oran,
Yes, I assume also, exception has originated from a deliver_sm packet. I'm going to try to capture bytes of the deliver_sm packet and send you as soon as posible.
I was using smppapi ver,0.3.7 but yestarday I have updated to new 0.3.9 version but that did not make any change.
Thanks again.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Oran,
Just to keep you updated, I have included a "snoop" rutine into packetReceived function but when I try to replicate the fail I found that program thread stop (fail) before it can get on packetReceived and only get data without the bug.. Looks like the fail start before the api can get onto packetReceived function.
However, today I'm going to work with technician from SMSC looking for this information from SMSC side.
Regards.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You don't need to customise the smppapi. You should be able to use the snoop streams functionality built into the SMSC link. Have a look at the javadocs for SmscLink.setSnoopStreams - if you give it (for example) a FileOutputStream for the snoopIn parameter, every byte read from the SMSC will be written to the file before it is passed on to the rest of the smppapi.
You could also use wireshark...very useful for capturing and analysing network comms.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Oran,
Following your suggestion, bellow is the hex code I got using smscLink.setSnoopStreams(SnoopIn, SnoopOut). Please note that I has ported binary data to hex. Also I can send you bout files by mail if you need it. Please confirm your SourceForge mail.
Hex code bellow has to show only MO messages, first one succesfully with Text=Juego (from phone number 05650252084013) and last one with blank text (same phone number).
The hex string you posted is impossible to decode reliably because you have output some bytes using only 1 character. You should have zero-padded single digits (such as "00 0a 04") so that it was easy to split the string into individual bytes. As it stands, at position 3 in the string it is not possible to determine if the next byte is 0x1 or 0x11 (I could guess 0x11 as that would allow me to adequately decode a bind_receiver_resp but there's no point in guessing when trying to diagnose a problem).
Sending me the binary files would probably be the best. You can email me at my Sourceforge email address - my username is orank, which should be appended with -at- users.sourceforge.net
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ok, there is indeed a problem with the encoding of the deliver_sm packet you are receiving. Here is my decode of the offending packet, which is the second deliver_sm packet you received in your session:
00 00 00 37 length = 55
00 00 00 05 id = deliver_sm
00 00 00 00 status = 0
00 00 00 11 sequence = 17
43 4d 54 00 service type = CMT
01 09 xx xx xx xx xx xx xx xx xx xx xx xx xx xx 00 source address
01 09 xx xx xx xx 00 destination address
00 esm_class
00 protocol_id
01 priority
00 scheduled delivery time
00 expiry time
00 registered
00 replace if present
00 data_coding
00 default_msg
00 sm_length
00 ??
As you can see your command length specifies the packet length of 55 bytes which is the number of bytes available. However, your sm_length value indicates that the message is 0 bytes in length. The smppapi has parsed 54 bytes correctly and knows there are more bytes in the packet because of the command length value. It therefore passes any remaining bytes to the TLVTable for it to parse.
The TLVTable cannot parse a single '0' byte and the exception occurs (but only when you call some method which causes TLVTable to call its parseAllOpts method)
My guess is that the remote side of the link has incorrectly implemented the SMPP protocol for blank messages. A message is not a nul-terminated string - it is just an array of bytes the length of which is specified by sm_length. If that 0x00 byte is intended to be part of the blank message, then sm_length should be 1, indicating there is a single byte in the message. If the message should indeed be zero bytes long as indicated by sm_length, then that final 0x00 byte should not be present and the command_length should be 54 (0x36).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Just to let you know that I finally had to make an modification to the code of
parseAllOptions because the SMSC could never correcting the error when sending
blank MO.
Sorry for not to sent this before.
Following is a copy of the modifieded Code:
while (p < opts.length) {
Object val = null;
//fboesche
//Modified to resolve the error in sending blank MO from Wau.
//21-Oct-2009 Add an ArrayIndexOutOfBoundsException try catch
//for ArrayIndexOutOfBoundsException
try{
Tag t = Tag.getTag(SMPPIO.bytesToInt(opts, p, 2));
Encoder enc = t.getEncoder();
int l = SMPPIO.bytesToInt(opts, p + 2, 2);
val = enc.readFrom(t, opts, p + 4, l);
map.put(t, val);
p += 4 + l;
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("Blank MO error - ArrayIndex Out of Bounds: " +
e);
byte chapus = {};
opts = chapus;
}
//fboesche
//End of mofication
}
Thanks again for your help.
Regards,
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Wow so your SMSC provider is keeping their broken implementation of their
protocol the way it is? That seems crazy to me. Any SMPP implementation, not
just this smppapi, will be confused by that stray nul byte. Ah well, SEP.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Oran
Please help me with this:
I'm getting a Connection Fatal exception in receiver thread (RX) when SMSC sent sms (MO) with blank message text (I mean without text on message data).
After that I can't receive any more MO messages until restart connection.
This is a copy of logger:
java.lang.ArrayIndexOutOfBoundsException: 1
at ie.omk.smpp.util.SMPPIO.bytesToInt(Unknown Source)
at ie.omk.smpp.message.tlv.TLVTable.parseAllOpts(Unknown Source)
at ie.omk.smpp.message.tlv.TLVTable.getLength(Unknown Source)
at ie.omk.smpp.message.SMPPPacket.getLength(Unknown Source)
at ie.omk.smpp.Connection.readNextPacketInternal(Unknown Source)
at ie.omk.smpp.Connection.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Any idea of what's wrong?
Thank you in advance for your help.
fboesche.
Hi Oran,
I going to talk with SMSC technician to see if they can fix the blank sms bug you found! from their side.
I'm not sure, but I remember that they said they going to implement TLVTable on their SMSC applications server. I going to ask also about it.
Questions:
Thanks again.
On question 1: not necessarily. the TLVTable in 0.3.x lazy-parses for inbound packets. That is, it doesn't actually parse the TLVs out of the bytes until something is done on the TLVTable. There are various ways in which this might happen - a simple example is calling SMPPPacket.getLength. Since it needs to know the length of the TLVTable, it calls TLVTable.getLength which then causes parseAllOpts to be invoked.
On your second question: you could probably modify the implementation of TLVTable to be resilient to invalid bytes. For example, you could modify parseAllOpts to not throw an exception if it cannot parse out the TLVTable, it could simply ignore the invalid data. That approach would work in this specific case but it would prevent you from being able to use TLVs in deliver_sm packets.
Ok, I understand that.
Trying to fix it in the right way I'm going to talk with the SMSC technician and only if they can't or don't want to do it, I will go to modify the code.
Oran, kindly appreciated your help. I will like to let you know how finally I can fix it.
Regards,
Not much info but my best guess is that the smppapi has read the command length of what I assume is a deliver_sm packet. It has parsed all the mandatory parameters but sees that there are still bytes available which implies there are TLVs. It then tries to parse the TLV table but in actual fact the bytes are not available, hence the exception.
If possible, can you capture the bytes of the deliver_sm packet and either email them to me (at my sourceforge address) or grab a hex dump of the deliver_sm packet and post it here so that I can analyse the packet to see if this is something wrong with the smppapi parsing mechanism. What version of smppapi is this happening with?
Thank you Oran,
Yes, I assume also, exception has originated from a deliver_sm packet. I'm going to try to capture bytes of the deliver_sm packet and send you as soon as posible.
I was using smppapi ver,0.3.7 but yestarday I have updated to new 0.3.9 version but that did not make any change.
Thanks again.
Hi Oran,
Just to keep you updated, I have included a "snoop" rutine into packetReceived function but when I try to replicate the fail I found that program thread stop (fail) before it can get on packetReceived and only get data without the bug.. Looks like the fail start before the api can get onto packetReceived function.
However, today I'm going to work with technician from SMSC looking for this information from SMSC side.
Regards.
You don't need to customise the smppapi. You should be able to use the snoop streams functionality built into the SMSC link. Have a look at the javadocs for SmscLink.setSnoopStreams - if you give it (for example) a FileOutputStream for the snoopIn parameter, every byte read from the SMSC will be written to the file before it is passed on to the rest of the smppapi.
You could also use wireshark...very useful for capturing and analysing network comms.
Hi Oran,
Following your suggestion, bellow is the hex code I got using smscLink.setSnoopStreams(SnoopIn, SnoopOut). Please note that I has ported binary data to hex. Also I can send you bout files by mail if you need it. Please confirm your SourceForge mail.
Hex code bellow has to show only MO messages, first one succesfully with Text=Juego (from phone number 05650252084013) and last one with blank text (same phone number).
000118000100000001000108000150000000200010800015000000030003b00050000000550001080001500000005000370005000000056
Hoope this can help.
Regards,
Sorry Oran, I have a error on my last message:
The correct text has to be:
Hex code bellow has to show only two MO messages,......
Regards
The hex string you posted is impossible to decode reliably because you have output some bytes using only 1 character. You should have zero-padded single digits (such as "00 0a 04") so that it was easy to split the string into individual bytes. As it stands, at position 3 in the string it is not possible to determine if the next byte is 0x1 or 0x11 (I could guess 0x11 as that would allow me to adequately decode a bind_receiver_resp but there's no point in guessing when trying to diagnose a problem).
Sending me the binary files would probably be the best. You can email me at my Sourceforge email address - my username is orank, which should be appended with -at- users.sourceforge.net
Please check your mail. I sent binary file.
Ok, there is indeed a problem with the encoding of the deliver_sm packet you are receiving. Here is my decode of the offending packet, which is the second deliver_sm packet you received in your session:
00 00 00 37 length = 55
00 00 00 05 id = deliver_sm
00 00 00 00 status = 0
00 00 00 11 sequence = 17
43 4d 54 00 service type = CMT
01 09 xx xx xx xx xx xx xx xx xx xx xx xx xx xx 00 source address
01 09 xx xx xx xx 00 destination address
00 esm_class
00 protocol_id
01 priority
00 scheduled delivery time
00 expiry time
00 registered
00 replace if present
00 data_coding
00 default_msg
00 sm_length
00 ??
As you can see your command length specifies the packet length of 55 bytes which is the number of bytes available. However, your sm_length value indicates that the message is 0 bytes in length. The smppapi has parsed 54 bytes correctly and knows there are more bytes in the packet because of the command length value. It therefore passes any remaining bytes to the TLVTable for it to parse.
The TLVTable cannot parse a single '0' byte and the exception occurs (but only when you call some method which causes TLVTable to call its parseAllOpts method)
My guess is that the remote side of the link has incorrectly implemented the SMPP protocol for blank messages. A message is not a nul-terminated string - it is just an array of bytes the length of which is specified by sm_length. If that 0x00 byte is intended to be part of the blank message, then sm_length should be 1, indicating there is a single byte in the message. If the message should indeed be zero bytes long as indicated by sm_length, then that final 0x00 byte should not be present and the command_length should be 54 (0x36).
Hi Oran,
Just to let you know that I finally had to make an modification to the code of
parseAllOptions because the SMSC could never correcting the error when sending
blank MO.
Sorry for not to sent this before.
Following is a copy of the modifieded Code:
while (p < opts.length) {
Object val = null;
//fboesche
//Modified to resolve the error in sending blank MO from Wau.
//21-Oct-2009 Add an ArrayIndexOutOfBoundsException try catch
//for ArrayIndexOutOfBoundsException
try{
Tag t = Tag.getTag(SMPPIO.bytesToInt(opts, p, 2));
Encoder enc = t.getEncoder();
int l = SMPPIO.bytesToInt(opts, p + 2, 2);
val = enc.readFrom(t, opts, p + 4, l);
map.put(t, val);
p += 4 + l;
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("Blank MO error - ArrayIndex Out of Bounds: " +
e);
byte chapus = {};
opts = chapus;
}
//fboesche
//End of mofication
}
Thanks again for your help.
Regards,
Wow so your SMSC provider is keeping their broken implementation of their
protocol the way it is? That seems crazy to me. Any SMPP implementation, not
just this smppapi, will be confused by that stray nul byte. Ah well, SEP.