Working on a live chat app on Android using XMPP framework / OpenFire and just transferred to a new cloud server but I’m having some problems with the old Android Users Connecting. New users can log in fine and connect to the OpenFire Server.
With the old user accounts it fails the connection the 1st time, but then the 2nd time it connects. Anyone knows what the issue could be?
Can't figure out what the issue is.
hi if your trying to connect xmpp with openfire then just give ssl permission to XMPPTCPConnectionConfiguration with smack library,
private XMPPTCPConnectionConfiguration buildConfiguration() throws XmppStringprepException {
XMPPTCPConnectionConfiguration.Builder builder =
XMPPTCPConnectionConfiguration.builder();
builder.setHost(Common.HOST);
builder.setPort(PORT);
builder.setCompressionEnabled(false);
builder.setDebuggerEnabled(true);
builder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
builder.setSendPresence(true);
if (Build.VERSION.SDK_INT >= 14) {
builder.setKeystoreType("AndroidCAStore");
builder.setKeystorePath(null);
} else {
builder.setKeystoreType("BKS");
String str = System.getProperty("javax.net.ssl.trustStore");
if (str == null) {
str = System.getProperty("java.home") + File.separator + "etc" + File.separator + "security"
+ File.separator + "cacerts.bks";
}
builder.setKeystorePath(str);
}
DomainBareJid serviceName = JidCreate.domainBareFrom(Common.HOST);
builder.setServiceName(serviceName);
return builder.build();
}
and call this when you are connecting with server here is example see
XMPPTCPConnectionConfiguration config = buildConfiguration();
SmackConfiguration.DEBUG = true;
this.connection = new XMPPTCPConnection(config);
this.connection.connect();
for more details visit this example
thanks hope this will help you to solve your problem (Y).
To connect to openfire ( any xmpp server ) from android device using SSL follow this with Smack
// Set key for SSL connection
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
config.setKeystoreType("AndroidCAStore");
config.setKeystorekeyPath(null);
} else {
config.setKeystoreType("BKS");
String keyPath = System.getProperty("javax.net.ssl.trustStore");
if (keyPath == null)
keyPath = System.getProperty("java.home") + File.separator + "etc"
+ File.separator + "security" + File.separator + "certs.bks";
config.setKeystorekeyPath(keyPath);
}
}
// Now set custom SSL to configuration
try {
SSLContext ssl = SSLContext.getInstance("TLS");
ssl.init(null, new TrustManager[]{new TLSUtils.AcceptAllTrustManager()}, null);
ssl.getServerSessionContext().setSessionTimeout(10 * 1000);
config.setCustomSSLContext(ssl);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
config.setSecurityMode(Connectionconfig.SecurityMode.required);
// config is type of XMPPTCPConnectionConfiguration
Related
I want to send some files to an FTP server from Android. I have the server IP address, username, and password. I tried to connect to it from Filezilla and it works, however, if I try to connect from Android it fails. I get status code 530 from ftpClient.getReplyCode().
According to https://en.wikipedia.org/wiki/List_of_FTP_server_return_codes the status code means that the login didn't work. ftpClient.login returns false.
So I tried mounting an FTP server with node.js and could connect and upload files perfectly. Then I tried to connect to another test server ftp://test.rebex.net/ using username: demo and password: password and the login works too (uploading files fails because its a test account).
But why do I fail to log in to that specific server from Android but not from Filezilla?
My code:
uploading_to_local_server = true;
FTPClient ftpClient = new FTPClient();
try {
if(port == 0){
ftpClient.connect(ftpserver);
}else {
ftpClient.connect(ftpserver, port);
}
ftpClient.setSoTimeout(10000);
ftpClient.enterLocalPassiveMode();
Log.d(TAG,"FTP. TRYING TO LOGIN ");
Boolean login_response = ftpClient.login(ftp_usr,ftp_psw);
mreplyCode = ftpClient.getReplyCode();
Log.d(TAG,"FTP. RESPONSE " + mreplyCode);
if (login_response) {
Log.d(TAG, "FTP. VIDEOS TO UPLOAD: LOGGED SUCCESFULLY");
//Logged.
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.setFileTransferMode(FTP.BINARY_FILE_TYPE);
//iterating through the videos
String video_upload_result = "Uknown Error";
ArrayList<HashMap<String, String>> list_videos_to_upload = dataBaseHelper.getVideosLocalserverH();
for (int counter = 0; counter < list_videos_to_upload.size(); counter++) {
video_upload_result = "Uknown Error";
//list_videos_to_upload.get(counter).put("imei", IMEI);
String video_path = list_videos_to_upload.get(counter).get("dir_route");
String video_name = list_videos_to_upload.get(counter).get("video_name");
String vid_id = list_videos_to_upload.get(counter).get("id");
String sync_status = list_videos_to_upload.get(counter).get("sync");
Log.d(TAG, "VIDEOS TO UPLOAD: " + video_path + " ID: " + vid_id);
//Log.d(TAG, "WIFI STATUS: " + mWifi.isConnected() + " DATA STATUS: " + wData.isConnected());
video_upload_result = try_upload_video_to_ftpserver(ftpClient, video_name, remote_path, video_path);
Log.d(TAG, "VIDEOS TO UPLOAD: " + video_path + " RESULT: " + video_upload_result);
if(video_upload_result.equals("Succes")) {
Log.d(TAG, "TESTING UPLOAD: VIDEO ID: "+ vid_id);
dataBaseHelper.modVideos_Localserver(Collections.singletonList(vid_id));
}else if(video_upload_result.equals(video_path + ": open failed: ENOENT (No such file or directory)")){
Log.d(TAG, "TESTING UPLOAD: ERROR CATCHED. FILE NOT FOUND: "+ vid_id);
dataBaseHelper.modVideos_Localserver(Collections.singletonList(vid_id));
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
Log.d(TAG, "Error Sleeping thread");
e.printStackTrace();
}
}
}
ftpClient.logout();
ftpClient.disconnect();
}catch (IOException e) {
e.printStackTrace();
}
Log.d(TAG, "UPLOADING LOOP ENDED: ");
uploading_to_local_server = false;
EDIT:
Finally Managed to make it work.
Turns out the server only accepted connections through ftps.
So I changed:
FTPClient ftpClient = new FTPClient();
for
FTPSClient ftpClient = new FTPSClient("TLS", false);
and I managed to connect to the server but still coudn´t upload videos because the server also only accepts encrypted data, so I added:
ftpClient.execPROT("P"); // encrypt data channel
And now I can finally upload videos to that server.
After connect to FTP, and then login to FTP.
If to login is success, then you need to let localPassiveMode:
ftpClient.enterLocalPassiveMode();
Then you can upload file to FTP server.
Thank you
I'm developing an app that sends data over a WiFi intranet connection and all the data is sent in one package on Android 5 but in several packages in Android 8.0.1
So for the code below in Android 5 I get "This is a test" and in Android 8.0.1
"T" (one packet)
"hi"
" i"
"s"
" a"
" test"
Does anybody would know what is happening?
This is part of the code
if(!Connected)
{
//myClient.addListener();
myClient = new Socket(serverName, port);
myClient.setTcpNoDelay(true);
//myClient.on("new message", onNewMessage);
Connected=true;
inFromServer = myClient.getInputStream();
in = new DataInputStream(inFromServer);
}
if(Connected)
{
//updateText.setText("Just connected to " + client.getRemoteSocketAddress());
OutputStream outToServer = myClient.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
if(msgToSend.isEmpty())
{
out.writeChars("This is a test\r\n");
//out.writeBytes("This is a test\r\n");
}
else
{
out.writeChars(msgToSend);
//out.writeBytes(msgToSend);
}
out.flush();
while(waitingData)
{
if(in.available()>0)
{
XChar = in.readByte();
if(XChar>=32)
{
inBuffer+= Byte.toString(XChar);
}
else
{
waitingData= false;
}
}
}
}
don't know why, the app when connecting to the SQL Server that is on the same network as the device, I can connect to it without any problems, but now I need to connect from the device over the internet to the SQL Server, isn't working, don't know why. I have a button to test the connection and it will call a method that contains this, the method is on background (AsyncTaskRunner)
try
{
String host, port, dbname, user, password, instance;
host = _editTextHost.getText().toString();
port = _editTextPort.getText().toString();
instance = _editTextInstance.getText().toString();
dbname = _editTextDbName.getText().toString();
user = _editTextUser.getText().toString();
password = _editTextPass.getText().toString();
String driver = "net.sourceforge.jtds.jdbc.Driver";
String conString;
if (TextUtils.isEmpty(port))
{
conString = "jdbc:jtds:sqlserver://" + host + ";databaseName=" + dbname + ";instance=" + instance;
}
else
{
conString = "jdbc:jtds:sqlserver://" + host + ":" + port + ";databaseName=" + dbname + ";instance=" + instance;
}
Connection con;
Class.forName(driver);
con = DriverManager.getConnection(conString, user, password);
con.close();
conSuccess = true;
}
catch (Exception e)
{
e.printStackTrace();
Log.e("SQLConfig", "Fail to connect");
Log.e("SQLConfig", e.toString());
Log.e("SQLConfig", e.getMessage());
}
return null;
When I do try to connect to the SQL Server on the same network works without any problems, but when I activate the 4g on the device I allways get the same error, that it can't find the instance. But if I connect to the server through the "SQL Server Management Studio" using the same information I can connect to the server without any problems.
I'm using the jtds driver, 1.3.1.
What could be doing this? Thanks
P.S. I all rdy have read some stuff about webservice, but I want to remove this option for now out of the picture
Edit 1: To clarify, I can connect to the server using the credentials on the version of Windows CE of the program or SQL Server Management Studio. When I put the outside IP and all the require information it connects to the server, it not connect on the Android only
Well by changing the conString a little I was able to connect without any problems either from the localnetwork or the internet.
if (TextUtils.isEmpty(port))
{
conString = "jdbc:jtds:sqlserver://" + host + ";databaseName=" + dbname + ";instance=" + instance;
}
else
{
conString = "jdbc:jtds:sqlserver://" + host + ":" + port + ";databaseName=" + dbname + ";instance=" + instance;
}
To
if (TextUtils.isEmpty(port))
{
conString = "jdbc:jtds:sqlserver://" + host + "/" + instance + ";DatabaseName=" +dbname;
}
else
{
conString = "jdbc:jtds:sqlserver://" + host + ":" + port + "/" + instance + ";DatabaseName=" + dbname;
}
Now works without any problems either using the public host or the localnetwork to access the db.
In My Android application I get xmpp connection initially using server_nm and 5222 port on login and done single chat message send and receive,but at time of file transfer, How I configure connection with proxy_server and 7777 port which use for file transfer?
public class XmppManager {
private static final int packetReplyTimeout = 500; // millis
private String server=server_nm;
private int port=5222;
private ConnectionConfiguration config;
private XMPPConnection connection;
String group_name,userid;
private ChatManager chatManager;
private MessageListener messageListener;
private Handler mHandler;
PacketFilter filter;
Message message;
Context context;
public static boolean IBB_ONLY = (System.getProperty("ibb") != null);//true;
protected static final String STREAM_DATA_FIELD_NAME = "stream-method";
private StreamNegotiator byteStreamTransferManager;
private StreamNegotiator inbandTransferManager;
// constructor
public XmppManager(String server, int port) {
this.server = server;
this.port = port;
}
// to initialize connection
public void init(Context c) throws XMPPException {
System.out.println(String.format(
"Initializing connection to server %1$s port %2$d", server,
port));
SmackConfiguration.setPacketReplyTimeout(50000);
config = new ConnectionConfiguration(server, port);
config.setSASLAuthenticationEnabled(false);
config.setSecurityMode(SecurityMode.disabled);
// group chat invitation
ProviderManager.getInstance().addExtensionProvider("x",
"http://jabber.org/protocol/muc#user",
new GroupChatInvitation.Provider());
// offline msgtime
ProviderManager.getInstance().addExtensionProvider("x",
"jabber:x:delay", new DelayInformationProvider());
//file transfer method
ProviderManager.getInstance().addIQProvider("query","http://jabber.org/protocol/bytestreams", new BytestreamsProvider());
ProviderManager.getInstance().addIQProvider("query","http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());
ProviderManager.getInstance().addIQProvider("query","http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());
ProviderManager.getInstance().addIQProvider("si","http://jabber.org/protocol/si", new StreamInitiationProvider());
ProviderManager.getInstance().addIQProvider("open","http://jabber.org/protocol/ibb", new OpenIQProvider());
ProviderManager.getInstance().addIQProvider("close","http://jabber.org/protocol/ibb", new CloseIQProvider());
ProviderManager.getInstance().addExtensionProvider("data","http://jabber.org/protocol/ibb", new DataPacketProvider());
// v-card integration
ProviderManager.getInstance().addIQProvider("vCard", "vcard-temp", new VCardProvider());
connection = new XMPPConnection(config);
connection.connect();
System.out.println("Connected: " + connection.isConnected());
chatManager = connection.getChatManager();
context = c;
Intent i = new Intent(context, MyService.class);
context.startService(i);
}
// login to xmpp server
public void performLogin(String username, String password,String resource)
throws XMPPException {
if (connection != null && connection.isConnected()) {
System.out.println("connection on presence send" + connection.isConnected() + " " + username + " " + password);
connection.login(username, password,resource);
setStatus(true, "Online");
Presence presence = new Presence(Presence.Type.available);
connection.sendPacket(presence);
}
}
//using this code I try to send file
public void sendfileafterresponse(String filenm,String filereceiverid )
{
FileTransferNegotiator.IBB_ONLY = true;
this.setServiceEnabled(connection, true);
FileTransferManager manager = new FileTransferManager(connection);
OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(filereceiverid + "#chat.bobl.us/" + filereceiverid);
File file = new File(filenm);
try {
System.out.println("file send to" + filenm + filereceiverid);
transfer.sendFile(file, "test_file");
} catch (XMPPException e) {
e.printStackTrace();
}
while(!transfer.isDone()) {
if(transfer.getStatus().equals(Status.error)) {
System.out.println("ERROR!!! " + transfer.getError());
} else if (transfer.getStatus().equals(Status.cancelled)
|| transfer.getStatus().equals(Status.refused)) {
System.out.println("Cancelled!!! " + transfer.getError());
}
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(transfer.getStatus().equals(Status.refused) || transfer.getStatus().equals(Status.error)
|| transfer.getStatus().equals(Status.cancelled)){
System.out.println("refused cancelled error " + transfer.getError());
} else {
System.out.println("Success");
}
}
}
}
If you still want to transfer files via smack directly, you basically have too options, as far as I understand the API.
1.
First you can use In Band transmission, that is enabled via
FileTransferNegotiator.IBB_ONLY = true;
This sends your file as base64 encoded message, the same way you are sending a normal message packet.
The second option is to use a streaming proxy. This one is way faster since it does not need to encode / decode the file to base64 but transmitts the data directly. Both devices connnect to the proxy server and share data on this.
To configure a streaming proxy you have to configure it on the server side and add the Providers to your client side connection (this should be done automatically on the latest asmack library).
I configured such a setup using the ejabberd service and mod_proxy65 Mod_proxy65
add to your /etc/ejabberd/ejabberd.yml, your ip adress and host should match the service you are using.
host: "proxy1.example.org"
name: "File Transfer Proxy"
ip: "200.150.100.1"
port: 7777
Then allow the firewall to communicate on this port, and you should be good to go.
However, I figured out, that the file transfer only is functional, if both clients are in the presence "available" if any of them is in another state, the sender receives "service- unavailabe" errors.
Don't rely on XMPP file transfer using aSmack/Smack as it is buly. Instead you can create a plugin which will upload files to the server and after successfully uploading the files send the absolute url of the file to the recipient so that he/she can download the file from there.
Hope this works !
I am currently developing android XMPP client to communicate with the Tigase server setup locally.Before starting development on Android I am writing a simple java code on PC to test connectivity with XMPP server.My XMPP domain is my pc name "mwbn43-1" and administrator username and passwords are admin and tigase respectively.
Following is the snippet of the code I am using
class Test {
public static void main(String args[])throws Exception
{
System.setProperty("smack.debugEnabled", "true");
XMPPConnection.DEBUG_ENABLED = true;
ConnectionConfiguration config = new ConnectionConfiguration("mwbn43-1", 5222);
config.setCompressionEnabled(true);
config.setSASLAuthenticationEnabled(true);
XMPPConnection con = new XMPPConnection(config);
// Connect to the server
con.connect();
con.login("admin", "tigase");
Chat chat = con.getChatManager().createChat("aaphadke#mwbn43-1",
new MessageListener() {
public void processMessage(Chat chat, Message message) {
// Print out any messages we get back to standard out.
System.out.println("Received message: " + message);
}
});
try {
chat.sendMessage("Hi!");
}
catch (XMPPException e) {
System.out.println("Error Delivering block");
}
String host = con.getHost();
String user = con.getUser();
String id = con.getConnectionID();
int port = con.getPort();
boolean i = false;
i = con.isConnected();
if (i)
System.out.println("Connected to host " + host + " via port " + port + " connection id is " + id);
System.out.println("User is " + user);
con.disconnect();
}
}
When I run this code I get following error
Exception in thread "main" Resource binding not offered by server:
at org.jivesoftware.smack.SASLAuthentication.bindResourceAndEstablishSession(SASLAuthenticatio n.java:416) at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:331)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:395)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:349)
at Test.main(Test.java:26)
I found this articles on the same problem but no concrete solution
here
Could anyone please tell me the solution for this problem.I checked the XMPPConnection.java file in the Smack API and it looks the same as given in the link solution.
Thanks,
Ameya
I found the solution to the problem as given in here
These are the lines I should add before I connect to the server
ConnectionConfiguration config = new ConnectionConfiguration("mwbn43-1", 5222);
config.setSASLAuthenticationEnabled(false);
XMPPConnection xmpp = new XMPPConnection(config);
Thanks for all your help
I think this is a problem with library, a bug. It does not handle protocol correctly. Before the user is authenticated there is no point of sending resource bind, hence it is not advertised by the server. The client should not complain about it.