AnsweredAssumed Answered

AbstractXMPPConnection: Connection closed with error SSLException: Read error Software caused connection abort

Question asked by Mattia on Oct 7, 2016

I'm trying to manage the case when the internet connection is lost, for do this i'm using a Broadcast Receiver that listen for changes on the network and reads the different connection types (TYPE_WIFI, TYPE_MOBILE, TYPE_NOT_CONNECTED). When the type is WIFI or MOBILE it starts the Smack (4.1) XMPP service and connects to the Ejabber server, instead when the type is NOT_CONNECTED it does the opposite (disconnect and stop the service). But if i try to disable internet the connection is immediately closed with an SSLException and only after the Broadcast receiver reads the change and try to disconnect from the server, in this way the service is stopped but on the server the client is still online, because it has not sent the stanza with the presence unavailable.

How can i prevent this error in order to correctly close the server connection?

 

Android studio log error:

10-06 17:07:58.164 29236-27660/com.mychatapp W/AbstractXMPPConnection: Connection closed with error
  javax
.net.ssl.SSLException: Read error: ssl=0xb80a0c40: I/O error during system call, Connection timed out
  at com
.android.org.conscrypt.NativeCrypto.SSL_read(Native Method)
  at com
.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:699)
  at java
.io.InputStreamReader.read(InputStreamReader.java:231)
  at java
.io.BufferedReader.read(BufferedReader.java:325)
  at org
.jivesoftware.smack.util.ObservableReader.read(ObservableReader.java:41)
  at org
.kxml2.io.KXmlParser.fillBuffer(KXmlParser.java:1515)
  at org
.kxml2.io.KXmlParser.peekType(KXmlParser.java:992)
  at org
.kxml2.io.KXmlParser.next(KXmlParser.java:349)
  at org
.kxml2.io.KXmlParser.next(KXmlParser.java:313)
  at org
.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1151)
  at org
.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$200(XMPPTCPConnection.java:937)
  at org
.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:952)
  at java
.lang.Thread.run(Thread.java:818)
10-06 17:07:58.164 29236-27660/com.mychatapp D/xmpp: ConnectionClosedOn Error!
10-06 17:07:58.194 29236-27660/com.mychatapp D/SMACK: XMPPConnection closed due to an exception (0)
10-06 17:07:58.194 29236-27660/com.mychatapp W/System.err: javax.net.ssl.SSLException: Read error: ssl=0xb80a0c40: I/O error during system call, Connection timed out
10-06 17:07:58.194 29236-27660/com.mychatapp W/System.err:  at com.android.org.conscrypt.NativeCrypto.SSL_read(Native Method)
10-06 17:07:58.194 29236-27660/com.mychatapp W/System.err:  at com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:699)
10-06 17:07:58.194 29236-27660/com.mychatapp W/System.err:  at java.io.InputStreamReader.read(InputStreamReader.java:231)
10-06 17:07:58.194 29236-27660/com.mychatapp W/System.err:  at java.io.BufferedReader.read(BufferedReader.java:325)
10-06 17:07:58.194 29236-27660/com.mychatapp W/System.err:  at org.jivesoftware.smack.util.ObservableReader.read(ObservableReader.java:41)
10-06 17:07:58.194 29236-27660/com.mychatapp W/System.err:  at org.kxml2.io.KXmlParser.fillBuffer(KXmlParser.java:1515)
10-06 17:07:58.194 29236-27660/com.mychatapp W/System.err:  at org.kxml2.io.KXmlParser.peekType(KXmlParser.java:992)
10-06 17:07:58.194 29236-27660/com.mychatapp W/System.err:  at org.kxml2.io.KXmlParser.next(KXmlParser.java:349)
10-06 17:07:58.194 29236-27660/com.mychatapp W/System.err:  at org.kxml2.io.KXmlParser.next(KXmlParser.java:313)
10-06 17:07:58.194 29236-27660/com.mychatapp W/System.err:  at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1151)
10-06 17:07:58.194 29236-27660/com.mychatapp W/System.err:  at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$200(XMPPTCPConnection.java:937)
10-06 17:07:58.194 29236-27660/com.mychatapp W/System.err:  at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:952)
10-06 17:07:58.194 29236-27660/com.mychatapp W/System.err:  at java.lang.Thread.run(Thread.java:818)
10-06 17:07:58.514 29236-29236/com.mychatapp V/NetworkChangeReceiver: Not connected to Internet
10-06 17:07:58.554 29236-29236/com.mychatapp V/NetworkChangeReceiver: Not connected to Internet

MyXMPP initialiseConnection and createSSlContext method

 
private void initialiseConnection() {

   XMPPTCPConnectionConfiguration.Builder config = XMPPTCPConnectionConfiguration
   .builder();
  config.setSecurityMode(ConnectionConfiguration.SecurityMode.ifpossible);
  config.setServiceName(serverAddress);
  config.setHost(serverAddress);
  config.setPort(5223);
  config.setDebuggerEnabled(true);

   SSLContext sslContext = null;

   try {
  sslContext = createSSLContext(context);
   } catch (KeyStoreException e) {
  e.printStackTrace();
   } catch (NoSuchAlgorithmException e) {
  e.printStackTrace();
   } catch (KeyManagementException e) {
  e.printStackTrace();
   } catch (IOException e) {
  e.printStackTrace();
   } catch (CertificateException e) {
  e.printStackTrace();
   }

  config.setCustomSSLContext(sslContext);

   XMPPTCPConnection.setUseStreamManagementResumptiodDefault(true);
   XMPPTCPConnection.setUseStreamManagementDefault(true);

  connection = new XMPPTCPConnection(config.build());
   XMPPConnectionListener connectionListener = new XMPPConnectionListener();
  connection.addConnectionListener(connectionListener);
}

private SSLContext createSSLContext(Context context) throws KeyStoreException,
   NoSuchAlgorithmException, KeyManagementException, IOException, CertificateException {

   KeyStore trustStore;
   InputStream in = null;
  trustStore = KeyStore.getInstance("BKS");

   in = context.getResources().openRawResource(R.raw.mychatapp_keystore);

  trustStore.load(in, "MyPassword123".toCharArray());

   TrustManagerFactory trustManagerFactory = TrustManagerFactory
   .getInstance(KeyManagerFactory.getDefaultAlgorithm());
  trustManagerFactory.init(trustStore);
   SSLContext sslContext = SSLContext.getInstance("TLS");
  sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
   return sslContext;
}





 

Network Change BroadcastReceiver

public class NetworkChangeReceiver extends BroadcastReceiver {

private MainActivity mActivity;

@Override
public void onReceive(final Context context, final Intent intent) {

   String status = NetworkUtil.getConnectivityStatusString(context);
   Log.v("NetworkChangeReceiver", status);

   Intent service_intent = new Intent(context, MyService.class);

   switch (status) {
   case "Wifi enabled":

  context.startService(service_intent);

  mActivity = new MainActivity();
  mActivity.getmService().xmpp.connect("onCreate");
   Log.v("NetworkChangeReceiver", "service started");

   break;
   case "Mobile data enabled":

  context.startService(service_intent);

  mActivity = new MainActivity();
  mActivity.getmService().xmpp.connect("onCreate");
   Log.v("NetworkChangeReceiver", "service started");

   break;
   case "Not connected to Internet":
  mActivity = new MainActivity();
  mActivity.getmService().xmpp.disconnect();

  context.stopService(service_intent);

   break;
   }

   Toast.makeText(context, status, Toast.LENGTH_LONG).show();
}


Outcomes