We have implemented FileTransfer feature with the new android 4.1.1 . Every thing works fine except while transferring file to an iphone client.Transfer fails when negotiating.
We get the following logs when transfer is successful with a windows smack client.
D/SMACK(25089): SENT (0): <iq to='[email protected]/QXmpp' id='tmfCy-335' type='set'><si xmlns='http://jabber.org/protocol/si' id='jsi_1094412687185521586' mime-type='image/jpeg' profile='http://jabber.org/protocol/si/profile/file-transfer'><file xmlns="http://jabber.org/protocol/si/profile/file-transfer" name="5_224724.jpg" size="630784" ><desc>normal</desc></file><feature xmlns="http://jabber.org/protocol/feature-neg"><x xmlns='jabber:x:data' type='form'><field var='stream-method' type='list-single'><option><value>http://jabber.org/protocol/bytestreams</value></option><option><value>http://jabber.org/protocol/ibb</value></option></field></x></feature></si></iq>
D/SMACK(25089): RECV (0): <iq from='[email protected]/QXmpp' to='[email protected]/Tablet' id='tmfCy-335' type='result'><si xmlns='http://jabber.org/protocol/si' profile='http://jabber.org/protocol/si/profile/file-transfer'><feature xmlns='http://jabber.org/protocol/feature-neg'><x xmlns='jabber:x:data' type='submit'><field type='list-single' var='stream-method'><value>http://jabber.org/protocol/bytestreams</value></field></x></feature></si></iq>
D/SMACK(25089): SENT (0): <iq to='192.168.100.239' id='tmfCy-341' type='get'><query xmlns='http://jabber.org/protocol/disco#items'></query></iq>
D/SMACK(25089): SENT (0): <iq to='[email protected]/QXmpp' id='tmfCy-353' type='set'><query xmlns='http://jabber.org/protocol/bytestreams' sid='jsi_1094412687185521586' mode='tcp'><streamhost jid='[email protected]/Tablet' host='192.168.100.133' port='7777'/><streamhost jid='[email protected]/Tablet' host='fe80::5cf8:a1ff:fe8b:b73b%p2p0' port='7777'/><streamhost jid='[email protected]/Tablet' host='fe80::5ef8:a1ff:fe8b:b73b%wlan0' port='7777'/><streamhost jid='proxy.192.168.100.239' host='192.168.100.239' port='7777'/></query></iq>
D/SMACK(25089): RECV (0): <iq from='[email protected]/QXmpp' to='[email protected]/Tablet' id='tmfCy-353' type='result'><query xmlns='http://jabber.org/protocol/bytestreams' sid='jsi_1094412687185521586'><streamhost-used jid='[email protected]/Tablet'/></query></iq>
D/SMACK(25089): RECV (0): <iq from='192.168.100.239' to='[email protected]/Tablet' id='4072246770' type='get'><ping xmlns='urn:xmpp:ping'/></iq>
D/SMACK(25089): SENT (0): <iq to='192.168.100.239' id='4072246770' type='result'></iq>
We get the following logs when transfer is unsuccessful with an iphone smack client:
D/SMACK(25089): SENT (0): <iq to='[email protected]/iPad' id='tmfCy-441' type='set'><si xmlns='http://jabber.org/protocol/si' id='jsi_1968597579584741254' mime-type='image/jpeg' profile='http://jabber.org/protocol/si/profile/file-transfer'><file xmlns="http://jabber.org/protocol/si/profile/file-transfer" name="5_224724.jpg" size="630784" ><desc>normal</desc></file><feature xmlns="http://jabber.org/protocol/feature-neg"><x xmlns='jabber:x:data' type='form'><field var='stream-method' type='list-single'><option><value>http://jabber.org/protocol/bytestreams</value></option><option><value>http://jabber.org/protocol/ibb</value></option></field></x></feature></si></iq>
D/SMACK(25089): RECV (0): <iq from='[email protected]/iPad' to='[email protected]/Tablet' type='result' id='tmfCy-441'><si xmlns='http://jabber.org/protocol/si'><feature xmlns='http://jabber.org/protocol/feature-neg'><x xmlns='jabber:x:data' type='submit'><field var='stream-method'><value>http://jabber.org/protocol/bytestreams</value></field></x></feature></si></iq>
D/SMACK(25089): SENT (0): <iq to='[email protected]/iPad' id='tmfCy-443' type='get'><query xmlns='http://jabber.org/protocol/disco#info'></query></iq>
D/SMACK(25089): RECV (0): <iq from='[email protected]/iPad' to='[email protected]/Tablet' type='error' id='tmfCy-443'><query xmlns='http://jabber.org/protocol/disco#info'/><error type='cancel' code='501'><feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>
By Comparing the logs i feel its a matter of setting an incorrect proxy for the xmpp login connection.
Code for XMPP login :
ProxyInfo proxy = new ProxyInfo(null, loc_IP, 7777, null,null);
I would really like to use it this way ,
ProxyInfo proxy = new ProxyInfo(ProxyType.SOCKS5, loc_IP, 7777, null,null);
, but then the login process fails.
= XMPPTCPConnectionConfiguration.builder()
.setProxyInfo(proxy)
.setServiceName(loc_IP)
.setHost(loc_IP)
.setPort(XMPP_PORT)
.setCompressionEnabled(false)
.setDebuggerEnabled(true)
.setCustomSSLContext(sslContext)
.setSecurityMode(SecurityMode.ifpossible)
.setHostnameVerifier(verifier)
.setUsernameAndPassword(username, pwd)
.setResource(resourcestring)
.build();
File transfer enabling service code :
ServiceDiscoveryManager sdm=ServiceDiscoveryManager.getInstanceFor(main.login.connection);
if (sdm == null) {
sdm = ServiceDiscoveryManager.getInstanceFor(main.login.connection);
sdm.addFeature("http://jabber.org/protocol/disco#info");
sdm.addFeature("jabber:iq:privacy");
sdm.removeFeature("http://jabber.org/protocol/ibb");
}
SmackConfiguration.DEBUG = true;
// FileTransfer Service
ProviderManager.addIQProvider("query",
"http://jabber.org/protocol/bytestreams",new BytestreamsProvider());
ProviderManager.addIQProvider("query",
"http://jabber.org/protocol/disco#items",new DiscoverItemsProvider());
ProviderManager.addIQProvider("query",
"http://jabber.org/protocol/disco#info",new DiscoverInfoProvider());
ProviderManager.addIQProvider("si","http://jabber.org/protocol/si",new StreamInitiationProvider());
fileTransferNegotiator = FileTransferNegotiator.getInstanceFor(main.login.connection);
fileTransferNegotiator.IBB_ONLY = false;
fileTransferManager = FileTransferManager.getInstanceFor(main.login.connection);
fileTransferManager.addFileTransferListener(fileTransferListener);
fileTransferListener =new FileTransferListener() {
@Override
public void fileTransferRequest(FileTransferRequest request) {
IncomingFileTransfer inComingFileTransfer = request.accept();
//followed by status handling code in a thread
}
};