Message body is null, raw received packets has the data

Hi,

I am using the latest version of smack and having problem receving data.

Smack debug window shows the raw received packet as expected, but when it is delieved to message listener the message body doesnt have the data.

< some encrypted data >

What i see a problem is, the data in the tag “tms” is encrypted and I am sure there is some processing that smack does to remove it.

Can you guess help to figure out what the problem is ?

Thanks

Avinash

I guess that there is no PacketExtensionProvider for tms registered and therefore the tms extension is not added to the resulting message instance. More info here: http://www.igniterealtime.org/builds/smack/docs/latest/documentation/providers.h tml

Thank you for the reply.

There were couple of threads with the same issue and the below post explained it too.

Can you guide me how can i have my own PacketExtensionProvider?

The solution is to write your own PacketExtensionProvider. There is bug in ***PacketParserUtil#parsePacketExtension(String elementName, String namespace, XmlPullParser parser)***, for which, probably, you need to have your own provider.

Here is what i have written

ProviderManager manager = ProviderManager.getInstance();

manager.addExtensionProvider(, , new PacketExtensionProvider() {

*** @Override***

*** public PacketExtension parseExtension(XmlPullParser parser)***

*** throws Exception {***

*** DefaultPacketExtension extension = new DefaultPacketExtension(***, ***);***

*** boolean done = false;***

*** int eventType = parser.getEventType();***

*** while (!done) {***

*** System.out.println(parser.getText());***

*** if (eventType == XmlPullParser.START_TAG) {***

*** String name = parser.getName();***

*** // If an empty element, set the value with the empty string.***

*** if (parser.isEmptyElementTag()) {***

*** extension.setValue(name,"");***

*** }***

*** // Otherwise, get the the element text.***

*** else {***

*** eventType = parser.next();***

*** System.out.println(parser.getName());***

*** if (eventType == XmlPullParser.TEXT) {***

*** String value = parser.getText();***

*** extension.setValue(name, value);***

*** done=true;***

*** }***

*** }***

*** }***

*** eventType = parser.next();***

*** }***

*** return extension;***

*** }***

});

The idea is to read the data from instance of XMLPullParser and extract what you need and put it in DefaultPacketExtension instance.

Your MessageListener should look something like this

@Override

public void processMessage(Chat chat, Message message) {

*** if (message.getType() == Type.error) {***

*** System.out.println(“error message :” + message.getBody());***

******* } else if (message.getType() == Type.normal) {***

*** DefaultPacketExtension extension = (DefaultPacketExtension) message.getExtension(, );***

*** String msg = extension.getValue();***

*** System.out.println(msg);***

*** }***

}

Since you had put data in DefaultPacketExtension, you will not find data in message.getBody() but instead in meesage.getExtension()

Hope this is clear

There is bug inPacketParserUtil#parsePacketExtension(String elementName, String namespace, XmlPullParser parser), for which, probably, you need to have your own provider.

Care to elaborate the bug, so we can investigate and if it’s a real bug, fix it?

This is the method in PacketParserUtils.java

public static PacketExtension parsePacketExtension(String elementName, String namespace, XmlPullParser parser)

throws Exception

{

// See if a provider is registered to handle the extension.

Object provider = ProviderManager.getInstance().getExtensionProvider(elementName, namespace);

if (provider != null) {

if (provider instanceof PacketExtensionProvider) {

return ((PacketExtensionProvider)provider).parseExtension(parser);

}

else if (provider instanceof Class) {

return (PacketExtension)parseWithIntrospection(

elementName, (Class<?>)provider, parser);

}

}

// No providers registered, so use a default extension.

DefaultPacketExtension extension = new DefaultPacketExtension(elementName, namespace);

boolean done = false;

while (!done) {

int eventType = parser.next();

if (eventType == XmlPullParser.START_TAG) {

String name = parser.getName();

// If an empty element, set the value with the empty string.

if (parser.isEmptyElementTag()) {

extension.setValue(name,"");

}

// Otherwise, get the the element text.

else {

eventType = parser.next();

if (eventType == XmlPullParser.TEXT) {

String value = parser.getText();

extension.setValue(name, value);

}

}

}

else if (eventType == XmlPullParser.END_TAG) {

if (parser.getName().equals(elementName)) {

done = true;

}

}

}

return extension;

}

parser.next() is invoked twice, due to which you will skip reading the text

I am unable to see a bug there. It appears to me that the code would work if you parse an simple extension

text bla blub

but not if you parse nested elements. But DefaultPacketExtension doesn’t support those anyways.

ok, in that case my understanding was wrong.

< some data >

My message was something like this. You mean to say the data inside tms tag wont be processed and that’s how the default implementation is!!!

Please note that is missing it’s closing element </some data>

is a place holder for text, not a tag