Smack 4.2.1-beta2-SNAPSHOT: No response received within reply timeout even when reply is received well within the specified PacketReplyTimeout

Smack version 4.2.2 still throwing response timeout exception even the reply stanza was received within timeout period. The observation was on Note3 happen for aTalk while doing IBR account registration. It happens for both the carbon and omemo devicelist stanzas in a single test instance. As the test is not carried out at initial apk launch, I believe android inherited JIT compilation time does not contribute to the observed problem; also unlikely due to slow device long process time since the problem happen on Note3.

Another observation is carbon throws at 10s timeout (the default aTalk global setting) but message shows 50s timeout which was intentionly set for omemo devicelist request.

===== an extraction of the debug log showing only relevant stanza ===============
01-12 05:37:04.553 D/SMACK: SENT (3): <iq id='8NKO8-376' type='set'><enable xmlns='urn:xmpp:carbons:2'/></iq>
01-12 05:37:04.693 D/SMACK: RECV (3): <iq xml:lang='en' to='test2@atalk.org/atalk' from='test2@atalk.org' type='result' id='8NKO8-376'/>
01-12 05:37:06.253 D/SMACK: SENT (3): <iq to='test2@atalk.org' id='8NKO8-388' type='get'><query xmlns='http://jabber.org/protocol/disco#info' node='eu.siacs.conversations.axolotl.devicelist'></query></iq><r xmlns='urn:xmpp:sm:3'/>
01-12 05:37:06.273 D/SMACK: RECV (3): <iq xml:lang='en' to='test2@atalk.org/atalk' from='test2@atalk.org' type='result' id='8NKO8-388'><query node='eu.siacs.conversations.axolotl.devicelist' xmlns='http://jabber.org/protocol/disco#info'><identity type='registered' category='account'/></query></iq>
01-12 05:37:14.563 E/aTalk: [111] impl.protocol.jabber.OperationSetBasicInstantMessagingJabberImpl.enableDisableCarbon().796 Failed to set carbon state for: test2@atalk.org/atalk to true
                            org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 50000ms (~50s). Waited for response using: IQReplyFilter: iqAndIdFilter (AndFilter: (OrFilter: (IQTypeFilter: type=error, IQTypeFilter: type=result), StanzaIdFilter: id=8NKO8-376)), : fromFilter (OrFilter: (FromMatchesFilter (full): null, FromMatchesFilter (ignoreResourcepart): test2@atalk.org, FromMatchesFilter (full): atalk.org)).
                                at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:253)
                                at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:208)
                                at org.jivesoftware.smackx.carbons.CarbonManager.setCarbonsEnabled(CarbonManager.java:311)
01-12 05:37:56.263 E/aTalk: [112] org.jivesoftware.smackx.omemo.OmemoManager.run() connectionListener.authenticated() failed to initialize OmemoManager: No response received within reply timeout. Timeout was 50000ms (~50s). Waited for response using: IQReplyFilter: iqAndIdFilter (AndFilter: (OrFilter: (IQTypeFilter: type=error, IQTypeFilter: type=result), StanzaIdFilter: id=8NKO8-388)), : fromFilter (OrFilter: (FromMatchesFilter (full): test2@atalk.org, FromMatchesFilter (full): null)).

Hm… I’ll try to take a look. What makes me wonder is, that I haven’t yet been able to reproduce this in the integration tests.

The rework of smack-omemo will soon be done. Maybe you want to give it a try? The API is unfortunately no longer the same, so you have to make some changes, but maybe it pays out?
In case you want to try it, you’ll have to compile Smack yourself from https://github.com/igniterealtime/Smack/pull/177 .

Maybe the new version solves your issue :slight_smile:

Yes, I would certainly integrated the new omemo library into aTalk but
will wait a week or two.
I just released aTalk into google playstore and need to do some final tidy
up.
By the way, do you have any omemo migration guide?

Below is a link to aTalk apk.
http://atalk.sytes.net

I am still fairy new in using git. By the way how do I pull in your source
into my local storage for compilation?

I’m working on it.

I’d recommend you to do the following in a working directory of your choice:

$ git clone https://github.com/igniterealtime/Smack.git
$ git remote add vanitasvitae https://github.com/vanitasvitae/Smack

That way you cloned the main smack repo and added my for as a remote.
Then you can checkout my branch and install it into your local maven repository:

$ cd Smack
$ git fetch vanitasvitae
$ git checkout vanitasvitae/storerework
$ gradle install

I’m not sure, which build system is used for building aTalk, but in gradle I included the mavenLocal repo like this:

repositories {
     mavenLocal()
}

If you need jar files, you can find those for example in ~/.m2/repository/org/igniterealtime/smack/smack-omemo/4.2.3-SNAPSHOT/

Thanks. Will take a look next week.

I have completed the initial porting to use the new omemo library and start
system testing.

Would appreciate for advice on the following:

  1. I see that you have obsoleted OmemoManager.regenerate(). Any reason?
    aTalk provides this option to user. User has used this to recovere from
    incomplete omemo database setup when connect to a slow server has timeout.

  2. Smack class FileBasedOmemoStore extends OmemoStore, whereas aTalk class
    SQLiteOmemoStore extends SignalOmemoStore
    It has been this way for aTalk. Do you see any problem with this?

  3. In aTalk earlier implementation, it uses the following method when
    encountered CorruptedOmemoKey in database so as to create new.
    OmemoService.getInstance().buildSessionFromOmemoBundle(omemoManager,
    omemoDevice, false);

I see that this is no more available. Do I need to do this with the new
implementation?

  1. I initi the OmemoManage with the following; is this correct?
    OmemoManager omemoManager = OmemoManager.getInstanceFor(connection);

  2. When a buddy added a new device, the previous OmemoManager seems to
    ignore published devicelist from this buddy. So any new message send to
    this buddy will not copy to the buddy new device? When and how OmemoManager
    will start cc omemo message to this new device?

aTalk has the following in AndroidOmemoService.java class to add new buddy
device. No sure if this correct?

private PEPListener buddyDeviceListUpdateListener = new PEPListener() {};

  1. How do you want me to feedback the test comment if any?
    Continue to use email or via forum - how do I name the new omemo if via
    forrum?

Regards,
CM ENg

Hi @cmeng!
Great to hear, that you are already testing :slight_smile:

  1. I find that the regenerate method is not really useful. There is no real use-case for it. Instead of throwing the whole identity away, I’d rather find a way to avoid sessions from breaking. If you really need a regenerate function, you can just manually delete all data associated to the old identity from the OmemoStore and then call OmemoManager.getInstanceFor(OmemoManager.randomDeviceId()).

  2. I dont fully understand the question, but it should be fine. Since you use a selfmade SQL store, extending SignalOmemoStore is he right choice to go. I advise you to wrap your SQL store in a SignalCachingOmemoStore in order to improve performance though (just call signalOmemoServiceInstance.setOmemoStoreBackend(new SignalCachingOmemoStore(yourSQLStoreInstance));.

  3. Yeah, I just realized, that a client dev doesn’t have access to such a function anymore. I’ll fix that by adding a method to the OmemoManager. In a perfect world, you wouldn’t need such function, but I agree that it is probably a good idea to expose this to the dev.

  4. By calling that code snippet you just get an instance of the OmemoManager. To initialize it, you’ll want to call either omemoManager.initialize(), or more suitable for older devices omemoManager.initializeAsync(initCallback). See the updated documentation.

  5. That should not have happened and shouldn’t happen anymore. As soon as a buddy adds a new device, you should get a deviceList update. If you then try to send a message, smack-omemo should instantly throw an UndecidedOmemoIdentityException due to that new device. If that doesn’t happen, please let me know!
    The code you have in your AndroidOmemoService should not be needed, as the OmemoManager already has a PEPListener (see these lines).

  6. I highly appreciate any form of feedback. The fastest way would be via XMPP (for example in the open_chat muc). If we have to exchange longer messages (eg. stanza logs), I think the forum is most suitable. You can use the naming scheme “smack-omemo (#177)” for issues :slight_smile:

Hi,

More questions:
7. Why localDeficeIdsOf() is requesting for SortedSet of deviceID. My
understanding is that each device is only associated with one deviceID.

/**

  • Returns a sorted set of all the deviceIds, the localUser has had
    data stored under in the store.
  • Basically this returns the deviceIds of all “accounts” of
    localUser, which are known to the store.
  • @param localUser BareJid of the user.
  • @return set of deviceIds with available data.
    */
    public abstract SortedSet localDeviceIdsOf(BareJid localUser);
  1. The return is date is not teddy with @return description text. I think
    it should be:
  • @return date if existent, otherwise null based on
    FileBaseOmemoStore.java implementation
    /**

  • Return the date in millis of the last message that was received
    from device ‘from’.

  1. It is possible (even though not very practical) to use multiple OmemoManagers on one device. Each OmemoManager then has its own deviceId. Therefore this method is needed. If you only ever use one OmemoManager on your device, this method can simply return a sorted set of just your one deviceId.

  2. You are right, I haven’t changed the javadoc. Thank you for the hint :slight_smile:

Edit: By the way if you include code in your comments/posts its better to put it in a block quote (ctrl + shift + 9).

I fixed the points you mentioned :slight_smile:

aTalk initialize the OmemoManager in two stages i.e.

  1. after xmpp connection connected
    OmemoManager omemoManager = OmemoManager.getInstanceFor(connection);

  2. on user authenticated - must only perform this upon user authenticated, other user not login exception.
    mOmemoManager.initializeAsync(this);

Then I receive the following error (attached below) in initializationFailed()
Look like aTalk cannot use OmemoManager.getInstanceFor(connection) without a deviceId being specified.

In the AndroidOmemoService.java I have to perform the following in order for OmemoManager initialization to work properly. Just wonder if omemoManager will include the below code, or leave to app to implement.

	XMPPTCPConnection connection = pps.getConnection();
        if (connection.getUser() != null) {
            user = connection.getUser().asBareJid();
        }
        else {
            user = pps.getAccountID().getFullJid().asBareJid();
        }

	int deviceId = (int) mOmemoStore.localDeviceIdsOf(user).first();
        OmemoManager omemoManager = OmemoManager.getInstanceFor(connection, deviceId);
========= debug log error message ==============
01-15 23:22:44.963 E/aTalk: [7] org.atalk.crypto.omemo.AndroidOmemoService.initializationFailed().116 Initialize OmemoManager failed: 
                            org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException: OMEMO Identity KeyPair is null for: leopard@atalk.org:-1
                                at org.atalk.crypto.omemo.SQLiteOmemoStore.loadOmemoIdentityKeyPair(SQLiteOmemoStore.java:371)
                                at org.atalk.crypto.omemo.SQLiteOmemoStore.loadOmemoIdentityKeyPair(SQLiteOmemoStore.java:66)
                                at org.jivesoftware.smackx.omemo.OmemoStore.replenishKeys(OmemoStore.java:199)
                                at org.jivesoftware.smackx.omemo.OmemoService.init(OmemoService.java:250)
                                at org.jivesoftware.smackx.omemo.OmemoManager.initialize(OmemoManager.java:244)
                                at org.jivesoftware.smackx.omemo.OmemoManager$2.run(OmemoManager.java:260)
                                at java.lang.Thread.run(Thread.java:818)
  1. You should get the instance of the OmemoManager before the connection gets connected.
  2. This is alright.

It looks like the exception gets thrown because your SQLiteOmemoStore is not correctly implemented.
Can you try to add your implementation to smack-omemo-signal’s SignalOmemoStoreTest in line 69?

The code snippet you provided to retrieve the BareJid will probably not be included in smack-omemo, but if it works for you, just use it.

  1. The parameter connection == null before connection is connected (before authenticated). Not sure if this is ok as pass in parameter connection is null.

Actually the error message is because OmemoManager device ID=UNKNOWN_DEVICE_ID for fetching; since I did not initialize the device ID. Should the OmemoManger take care of fetching it?

org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException: OMEMO Identity KeyPair is null for: leopard@atalk.org:-1

After the new implementation, the similar error message is still thrown this time for correct deviceID. On checking the sql database, it is really missing from DB. Not sure if this is due to my early testing with the half cooked code.
2. Any suggestion how to recover from this type of error i.e. corrupted or missing IdentityPreKeyPair beside doing the OmemoManager.regenerate?

  1. By the way, when and how is OmemoManager knows to initialize a new omemo data for a freshly installed device, as the following method has been obsoleted.

public boolean isFreshInstallation(OmemoManager omemoManager)

4, Testing on Note3, I still seeing the smack still throwing response timeout, but I think it is correct because of defaultPacketReplyTimeout of 5sec in SmackConfiguration. Even for Note8, it takes about 4.5s to publish the prekeys and receive the reply from my home server. I believe many of the free servers on network will failed to meet this timeout period of 5s. Actually the reply timeout also happen for enableDisableCarbon in the same test. On a safe side, aTalk I will change the global default timeout to 10sec. Possibly to also include the patch to ignore publish prekey timeout that I did for Smack v4.2.2.

  1. Following is a capture of the aTalk while testing on Note3. Do not quite understand why it throws reply timeout for id=FGapr-175 which is OK; shouldn’t the reply timeout is for id=‘FGapr-168’ i.e. publishing prekeys?
    Is my observation correct because of some race condition in smack?
============ Debug Log ==================
01-16 08:47:59.852 D/SMACK: SENT (1): <iq to='test2@atalk.org' id='FGapr-168' type='set'><pubsub xmlns='http://jabber.org/protocol/pubsub'><publish node='eu.siacs.conversations.axolotl.bundles:430747565'><item><bundle xmlns='eu.siacs.conversations.axolotl'><signedPreKeyPublic signedPreKeyId='1'>BRPO3WTznMiVhikIs+wJ9jUMFqHcqUsotYjgXwxB1wAJ</signedPreKeyPublic><signedPreKeySignature>2VGYV8+FlU9he6W6wbE7soKQAGWZZB/29Vtz+bYCOQTU92XTKeiKRPpTzJAJlbB5Nl4LfM7ScNe8j1cv+gFBCQ==</signedPreKeySignature><identityKey>BRH6nZPaSd1HQ6fn1LsfeHKkbloZxwIOHphZ0Gv7BTAr</identityKey><prekeys><preKeyPublic
01-16 08:48:04.272 D/SMACK: RECV (1): <iq xml:lang='en' to='test2@atalk.org/atalk' from='test2@atalk.org' type='result' id='FGapr-168'><pubsub xmlns='http://jabber.org/protocol/pubsub'><publish node=

01-16 08:48:04.292 D/SMACK: SENT (1): <iq to='test2@atalk.org' id='FGapr-175' type='get'><query xmlns='http://jabber.org/protocol/disco#info' node='eu.siacs.conversations.axolotl.devicelist'></query></iq>
01-16 08:48:05.702 D/SMACK: RECV (1): <iq xml:lang='en' to='test2@atalk.org/atalk' from='test2@atalk.org' type='result' id='FGapr-175'><query node='eu.siacs.conversations.axolotl.devicelist' xmlns='http://jabber.org/protocol/disco#info'><identity type='registered' category='account'/></query></iq>
01-16 08:48:09.293 E/aTalk: [17] org.atalk.crypto.omemo.AndroidOmemoService.initializationFailed().123 Initialize OmemoManager failed: 
                            org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 5000ms (~5s). Waited for response using: IQReplyFilter: iqAndIdFilter (AndFilter: (OrFilter: (IQTypeFilter: type=error, IQTypeFilter: type=result), StanzaIdFilter: id=FGapr-175)), : fromFilter (OrFilter: (FromMatchesFilter (full): test2@atalk.org, FromMatchesFilter (full): null)).
  1. I’m not too sure about that. In my personal test client, I do things in the following order:
connection = new XMPPTCPConnection(jid, password);
SignalOmemoService.setup();
OmemoService.getInstance().setOmemoStoreBackend(store);
OmemoManager manager = OmemoManager.getInstanceFor(connection);
...
connetion.login();
manager.initialize();

The UNKNOWN_DEVICE_ID is replaced by a deviceId from the store or a new random ID in the constructor of the OmemoManager (if the connection is authenticated when the manager gets created). If the connection is not authenticated on OmemoManager creation (as in the example above), a listener is registered on the connection, which will set a deviceId (from store or random), once the connection gets authenticated.

  1. That error should not happen in the first place and is probably caused by a broken store implementation. The only way to recover from that is by replacing the OmemoManager by a new one with a different deviceId and deleting all information of the old manager.

  2. The old method was error prone, since it was not clear, which data had to be present to qualify as a “non-fresh installation”, so now the manager checks if keys are available and creates missing keys on the fly.

  3. I’m still curious what might cause those timeouts, but unfortunately I haven’t figured it out yet.

  4. Thats strange. Both queries received a reply in less than 5 seconds (especially the second query), but there is still a no-response exception. Maybe the reply filter is erroneous?
    Maybe @Flow can help out here?

  1. You are right, I have tried out and it works. Will use your approach for aTalk.

  2. Actually I re-installed on an existing aTalk on Note3 of which the account was previously working. I recheck all the SQL implementation and everything is OK. and it is working with another previously installed account on the same device. I just cannot figure out how it got deleted. I kept the problem account data as it so I can try out your proposal to see if it works.

4/5. After I increase the smack reply timeout to 10 sec, Note3 previously having intermittent reply time is now OK.I think the 5s timeout is too marginal for Note 3 to meet.

  1. However now I am facing another problem when omemoService is trying to refreshAndRepublishDeviceList. Smack throws the following exception; however I cannot locate any stanza in the debug log that is related to id=2TvWa-313 i.e. reply timeout without stanza being sent. The problem happens 10/10 times on launch and only on NEW installed account on ejabberd server, which has no previous history of the new account publish data. . I believe it is something to do with PEPManager publish. aTalk UserAvatarManager implements a patch for 4.2.2 to take care of this problem. However I see 4.2.3 PEPManager implements something to that effect. I have not verify if the new patch on 4.2.3 works with ejabberd current implementation.

=============== Publish Error Log ======================
1-16 23:44:24.911 E/aTalk: [34] org.atalk.crypto.omemo.AndroidOmemoService.initializationFailed().125 Initialize OmemoManager failed:
org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 10000ms (~10s). Waited for response using: IQReplyFilter: iqAndIdFilter (AndFilter: (OrFilter: (IQTypeFilter: type=error, IQTypeFilter: type=result), StanzaIdFilter: id=2TvWa-313)), : fromFilter (OrFilter: (FromMatchesFilter (full): test2@atalk.org, FromMatchesFilter (full): null)).
at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:253)
at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:208)
at org.jivesoftware.smackx.pubsub.PubSubManager.getNode(PubSubManager.java:245)
at org.jivesoftware.smackx.pubsub.PubSubManager.getLeafNode(PubSubManager.java:331)
at org.jivesoftware.smackx.omemo.OmemoService.fetchDeviceList(OmemoService.java:601)
at org.jivesoftware.smackx.omemo.OmemoService.refreshAndRepublishDeviceList(OmemoService.java:702)
at org.jivesoftware.smackx.omemo.OmemoService.init(OmemoService.java:265)
at org.jivesoftware.smackx.omemo.OmemoManager.initialize(OmemoManager.java:244)
at org.jivesoftware.smackx.omemo.OmemoManager$2.run(OmemoManager.java:260)
at java.lang.Thread.run(Thread.java:818)

  1. I am trying to repair the corrupted identifyKeyPair (as previously mentioned) using the following approaches to emulate a regenerate process.
    a. Upon detected a corrupted or missing IdentifyKeyPair in loadOmemoIdentityKeyPair(OmemoDevice userDevice), I purge all the omemo data that are associated with this bad userDevice.
    b. I then check and confirm that the database are completely clean of the bad userDevice information
    c. Then I exit aTalk and relaunch, expecting that OmemoManager should now recreate the omemo database with a new deviceID for the account.
    d. However aTalk still reports the IdentifyKeyPair is missing with the new deviceID generated by OmemoManager; check and found not a single omemo data has been created in the DB for the new device.

I track and found OmemoManager did execute initBareJidAndDeviceId() correctly on user authentication and perform manager.setDeviceId(randomDeviceId()); But seems this is all it does without further action to create or publish omemo data for the new device.

Then I take an alternate approach to execute the following statement upon aTalk launch
OmemoManager.getInstanceFor(mConnection, OmemoManager.randomDeviceId()); to emulate regenerate as early recommended by you. But nothing get generate or store into the database just like before.

Please advice, some steps I missed out in my approach?

8 I see that OmemoManager#setTrustCallBack(0 can only initialize once. What about in the case of user reconnect when after his connection is dropped.
After reconnect, the connection will have a new instance, so is the omemoManager. Shouldn’t setTrustCallBack be executed again?

        OmemoManager omemoManager = OmemoManager.getInstanceFor(connection);
        omemoManager.setTrustCallback(((SQLiteOmemoStore) mOmemoStore).getTrustCallBack());
  1. That sounds like you didn’t call omemoManager.initialize(); once the manager gets instanciated and the connection is authenticated. The initialize() method is responsible for creating keys etc.

  2. The connection object should still be the same after reconnection if I remember correctly, so it should not be necessary to re-set the trust callback.

I checked and aTalk did call omemoManager.initializeAsync() but omemoManager throws the following exception instead.

Just try out, and found that the same exception is being thrown when I create a new account on the device.
I put break points on all SQLiteOmemStore methods access, found that omemoManager only access to two methods i.e.
a. loadOmemoIdentityKeyPair(OmemoDevice userDevice)
b localDeviceIdsOf(BareJid localUser)

and storeOmemoIdentityKeyPair(OmemoDevice userDevice, IdentityKeyPair identityKeyPair) is not called at all.

01-17 21:33:44.867 E/aTalk: [7] org.atalk.crypto.omemo.AndroidOmemoService.initializationFailed().129 Initialize OmemoManager failed: 
                            org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException: OMEMO IdentityKeyPair is missing for: leopard@atalk.org:1987465186
                                at org.atalk.crypto.omemo.SQLiteOmemoStore.loadOmemoIdentityKeyPair(SQLiteOmemoStore.java:386)
                                at org.atalk.crypto.omemo.SQLiteOmemoStore.loadOmemoIdentityKeyPair(SQLiteOmemoStore.java:70)
                                at org.jivesoftware.smackx.omemo.OmemoStore.replenishKeys(OmemoStore.java:199)
                                at org.jivesoftware.smackx.omemo.OmemoService.init(OmemoService.java:253)
                                at org.jivesoftware.smackx.omemo.OmemoManager.initialize(OmemoManager.java:244)
                                at org.jivesoftware.smackx.omemo.OmemoManager$2.run(OmemoManager.java:260)
                                at java.lang.Thread.run(Thread.java:818)

Thinking that it may be because Note-3 database is no more in a proper state after I have done some clean up. I proceed to do the exact same test on my Note-8 i.e. to create a new account. The exact same exception as above is being thrown i.e. Initialize OmemoManager failed: …

Testing on Note-8, I also found out that I cannot use the following for an existing good omemoDevice i.e. without the deviceID being specified. Otherwise OmemoManager throws the following exception .
OmemoManager.getInstanceFor(mConnection);

I have to revert to use the following for a good omemoDevice, then everything is ok.
OmemoManager.getInstanceFor(mConnection, deviceId);

On the safe side, I have also reverted to perform the above step only after xmpp connection as in old implementation. Unlike your test cast, aTalk implementation only starts user login after xmpp connection. As such the user is not defined at the point xmppConnection is constructed.

Note: all the while I was testing omemo on devices which already have the pre-installed omemo database from the smack-omemo v4.2.2

============ Exception thrown for good omemoDevice when use OmemoManager.getInstanceFor(mConnection r============== 
01-17 23:20:14.603 E/aTalk: [10164] org.atalk.crypto.omemo.AndroidOmemoService.initializationFailed().138 Initialize OmemoManager failed: 
                            org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException: OMEMO IdentityKeyPair is missing for: test2@atalk.org:-1
                                at org.atalk.crypto.omemo.SQLiteOmemoStore.loadOmemoIdentityKeyPair(SQLiteOmemoStore.java:386)
                                at org.atalk.crypto.omemo.SQLiteOmemoStore.loadOmemoIdentityKeyPair(SQLiteOmemoStore.java:70)
                                at org.jivesoftware.smackx.omemo.OmemoStore.replenishKeys(OmemoStore.java:199)
                                at org.jivesoftware.smackx.omemo.OmemoService.init(OmemoService.java:250)
                                at org.jivesoftware.smackx.omemo.OmemoManager.initialize(OmemoManager.java:244)
                                at org.jivesoftware.smackx.omemo.OmemoManager$2.run(OmemoManager.java:260)
                                at java.lang.Thread.run(Thread.java:762)