Today, i am trying to send an IQ message from a XMPP client to other in my project: Manage device behind NAT using TR069 combined with XMPP Chat Solutions.

TR069 XMPP NAT Traversal

But i get an error response from Server as following:

<error code='503'
<service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>

Reason we got this error because we are using custom XMPP IQ message. And we must implement an IQProvider to parse correctly our custom iq message.

I suppose our custom message looks like this:

<iq type="get" from="" to="">
    <connectionRequest xmlns="urn:broadband-forum-org:cwmp:xmppConnReq-1-0">

Then we will create two java classes name IQConnectionRequest and IQConnectionRequestProvider:

package vn.vnpttech.ssdc.nms.mediation.stbacs.packet;

import org.jivesoftware.smack.packet.IQ;

 * IQConnectionRequest
 * @author Vunb
 * @date Jun 5, 2015
 * @update Jun 5, 2015
public class IQConnectionRequest extends IQ {

    protected String username;
    protected String password;

    public String getUsername() {
        return username;

    public void setUsername(String username) {
        this.username = username;

    public String getPassword() {
        return password;

    public void setPassword(String password) {
        this.password = password;

    public String getChildElementXML() {
        String query
                = "<connectionRequest xmlns=\"urn:broadband-forum-org:cwmp:xmppConnReq-1-0\">"
                + "<username>%s</username>"
                + "<password>%s</password>"
                + "</connectionRequest>";
        return String.format(query, username, password);

     * Create new IQ Connection Request
     * @param username
     * @param password
    public IQConnectionRequest(String username, String password) {
        this.username = username;
        this.password = password;


package vn.vnpttech.ssdc.nms.mediation.stbacs.packet;

import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.provider.IQProvider;
import org.xmlpull.v1.XmlPullParser;

 * IQConnectionRequestProvider
 * @author Vunb
 * @date Jun 23, 2015
 * @update Jun 23, 2015
public class IQConnectionRequestProvider implements IQProvider {

    public IQ parseIQ(XmlPullParser parser) throws Exception {

        String username = "";
        String password = "";

        // Start parsing loop
        int eventType =;
        while (eventType != XmlPullParser.END_DOCUMENT) {
            switch (eventType) {
                case XmlPullParser.START_TAG:
                    String elementName = parser.getName();
                    if ("username".equals(elementName)) {
                        username = parser.nextText();
                    } else if ("password".equals(elementName)) {
                        password = parser.nextText();
                case XmlPullParser.END_TAG:
                    if (parser.getDepth() == 3) {
                        break outerloop;
            eventType =;
        return new IQConnectionRequest(username, password);


Then, at sending side, our code try to send custom XMPP IQ by using Smack 4.1.1 API:

    public void sendConnectionRequest(final String serialNumber, final String cpeUsername, final String cpePassword) throws XMPPException {
        String from = String.format("%s@%s/Smack", username, server);
        String to = String.format("%s@%s/Smack", serialNumber, server);

        IQConnectionRequest iq = new IQConnectionRequest(cpeUsername, cpePassword);

        // Note: XMPPConnection already initialized

At receiving side, we add a PacketListener to XMPPConnection to listen IQConnectionRequest message:

        // Add packet Listener
        PacketFilter getFilter = new IQTypeFilter(IQ.Type.GET);
        connection.addPacketListener(new PacketListener() {
            public void processPacket(Packet packet) {

                String from = packet.getFrom();
                String to = packet.getTo();

                final IQ request = new IQ() {
                    public String getChildElementXML() {
                        return childElement;
                final IQ result = IQ.createResultIQ(request);
                logger.debug("Reply: " + result.toXML());

        }, getFilter);

Finally, very important: Register our custom IQ Provider to Smack IQ Parser! Put it into somewhere in program that you like.

    static {
                        new IQConnectionRequestProvider());

Or by creating a smack.providers file in the META-INF directory of your JAR file. The file is an XML document that contains one or more iqProvider entries, as in the following example:

<?xml version="1.0"?>

Done! Do it yourself.

Wish you success !

Reference Links

About The Author

  • Hello World

    Bài viết rất hay, có demo trên PHP không ạ ?