The method rebuildSessionWith() is actually working. Corruption of the swordfish identityKeyPair is actually caused by aTalk method storeOmemoIdentityKey(); which mistakenly uses userDevice instead of contactDevice in storeOmemoIdentityKey() method.
After the correction in storeOmemoIdentityKey(), the last reported problems experienced by Note-3 and Note-8 is resolved, and Note-3 and Note-8 are now able to exchange omemo messages without problem.
The tests also demonstrated that the implementation of
PEPListener buddyDeviceListUpdateListener()
in aTalk is a must to take care and reconstruct the missing buddies identityKeys. Otherwise the previous reported problem will remain unresolved and omemo messaging will not work in aTalk.
I have included below aTalk implementation for your reference; for your consideration to include in your omemoManager
private final PEPListener deviceListUpdateListener
if you deem necessary:
/**
* PEPListener to add new buddy omemoDevice identityKey to identities table
* This is necessary otherwise newly installed client will always fail to communicate with
* buddies whom have been setup earlier.
*/
private PEPListener buddyDeviceListUpdateListener = new PEPListener()
{
@Override
public void eventReceived(EntityBareJid from, EventElement event,
org.jivesoftware.smack.packet.Message message)
{
// Our deviceList, so nothing more to do as it is handled in OmemoManager
if ((from == null) || from.equals(mOmemoManager.getOwnJid())) {
return;
}
for (ExtensionElement items : event.getExtensions()) {
if (!(items instanceof ItemsExtension)) {
continue;
}
final OmemoDevice userDevice = mOmemoManager.getOwnDevice();
for (ExtensionElement item : ((ItemsExtension) items).getItems()) {
if (!(item instanceof PayloadItem<?>)) {
continue;
}
PayloadItem<?> payloadItem = (PayloadItem<?>) item;
if (!(payloadItem.getPayload() instanceof OmemoDeviceListElement)) {
continue;
}
// Get the published Device List
OmemoDeviceListElement receivedDeviceList = (OmemoDeviceListElement) payloadItem.getPayload();
Set<Integer> deviceList = receivedDeviceList.getDeviceIds();
for (int deviceID : deviceList) {
final OmemoDevice contactDevice = new OmemoDevice(from.asBareJid(), deviceID);
IdentityKey preKey = null;
try {
preKey = (IdentityKey) mOmemoStore.loadOmemoIdentityKey(userDevice, contactDevice);
} catch (CorruptedOmemoKeyException e) {
preKey = null;
}
// Get the preKeys for missing buddy deviceID
if (preKey == null) {
aTalkApp.showToastMessage("Rebuild new session for missing: " + contactDevice);
try {
OmemoManager.getInstanceFor(mConnection).rebuildSessionWith(contactDevice);
} catch (InterruptedException | SmackException.NotConnectedException
| SmackException.NoResponseException | CorruptedOmemoKeyException
| CannotEstablishOmemoSessionException
| SmackException.NotLoggedInException e) {
logger.error("Could not rebuild session with: " + contactDevice + " Exception: ", e);
}
}
}
}
}
}
};