use of im.actor.core.network.mtp.entity.ProtoMessage in project actor-platform by actorapp.
the class ManagerActor method onInMessage.
@AutoreleasePool
private void onInMessage(byte[] data, int offset, int len) {
// Log.d(TAG, "Received package");
DataInput bis = new DataInput(data, offset, len);
try {
long authId = bis.readLong();
long sessionId = bis.readLong();
if (authId != this.authId || sessionId != this.sessionId) {
throw new IOException("Incorrect header");
}
if (authKey != null) {
EncryptedPackage encryptedPackage = new EncryptedPackage(bis);
int seq = (int) encryptedPackage.getSeqNumber();
if (seq != inSeq) {
throw new IOException("Expected " + inSeq + ", got: " + seq);
}
inSeq++;
// long start = Runtime.getActorTime();
EncryptedCBCPackage usEncryptedPackage = new EncryptedCBCPackage(new DataInput(encryptedPackage.getEncryptedPackage()));
byte[] ruPackage = serverUSDecryptor.decryptPackage(ByteStrings.longToBytes(seq), usEncryptedPackage.getIv(), usEncryptedPackage.getEncryptedContent());
EncryptedCBCPackage ruEncryptedPackage = new EncryptedCBCPackage(new DataInput(ruPackage));
byte[] plainText = serverRUDecryptor.decryptPackage(ByteStrings.longToBytes(seq), ruEncryptedPackage.getIv(), ruEncryptedPackage.getEncryptedContent());
// Log.d(TAG, "Package decrypted in " + (Runtime.getActorTime() - start) + " ms, size: " + len);
DataInput ptInput = new DataInput(plainText);
long messageId = ptInput.readLong();
byte[] ptPayload = ptInput.readProtoBytes();
receiver.send(new ProtoMessage(messageId, ptPayload));
} else {
long messageId = bis.readLong();
byte[] payload = bis.readProtoBytes();
receiver.send(new ProtoMessage(messageId, payload));
}
} catch (IOException e) {
Log.w(TAG, "Closing connection: incorrect package");
Log.e(TAG, e);
if (currentConnection != null) {
try {
currentConnection.close();
} catch (Exception e2) {
e2.printStackTrace();
}
currentConnection = null;
currentConnectionId = 0;
outSeq = 0;
inSeq = 0;
// Log.d(TAG, "Set connection #" + 0);
}
checkConnection();
}
}
use of im.actor.core.network.mtp.entity.ProtoMessage in project actor-platform by actorapp.
the class PusherActor method onReceive.
@Override
public void onReceive(Object message) {
if (message instanceof SendMessage) {
if (isEnableLog) {
Log.d(TAG, "Received SendMessage #" + ((SendMessage) message).mid);
}
SendMessage sendMessage = (SendMessage) message;
ProtoMessage holder = new ProtoMessage(sendMessage.mid, sendMessage.message);
unsentPackages.put(holder.getMessageId(), holder);
doSend(holder);
} else if (message instanceof ConnectionCreated) {
if (isEnableLog) {
Log.d(TAG, "Received ConnectionCreated");
}
// Marking all pending confirms as unsent
confirm.addAll(pendingConfirm);
pendingConfirm.clear();
// Resending unsent messages
ArrayList<ProtoMessage> toSend = new ArrayList<>();
for (ProtoMessage unsentPackage : unsentPackages.values()) {
if (isEnableLog) {
Log.d(TAG, "ReSending #" + unsentPackage.getMessageId());
}
toSend.add(unsentPackage);
}
// Sending SessionHello if there is no packages to sent
if (toSend.size() == 0) {
if (isEnableLog) {
Log.d(TAG, "Sending SessionHello");
}
toSend.add(new ProtoMessage(MTUids.nextId(), new SessionHello().toByteArray()));
}
doSend(toSend);
} else if (message instanceof SessionLost) {
if (isEnableLog) {
Log.d(TAG, "Sending SessionHello");
}
doSend(new ProtoMessage(MTUids.nextId(), new SessionHello().toByteArray()));
} else if (message instanceof ForgetMessage) {
if (isEnableLog) {
Log.d(TAG, "Received ForgetMessage #" + ((ForgetMessage) message).mid);
}
unsentPackages.remove(((ForgetMessage) message).mid);
} else if (message instanceof ConfirmMessage) {
if (isEnableLog) {
Log.d(TAG, "Confirming message #" + ((ConfirmMessage) message).mid);
}
confirm.add(((ConfirmMessage) message).mid);
if (confirm.size() >= ACK_THRESHOLD) {
if (askCancellable != null) {
askCancellable.cancel();
askCancellable = null;
}
askCancellable = schedule(new ForceAck(), 0);
} else if (confirm.size() == 1) {
if (askCancellable != null) {
askCancellable.cancel();
askCancellable = null;
}
askCancellable = schedule(new ForceAck(), ACK_DELAY);
}
} else if (message instanceof ForceAck) {
if (confirm.size() == 0) {
return;
}
MessageAck messageAck = buildAck();
doSend(new ProtoMessage(MTUids.nextId(), messageAck.toByteArray()));
} else if (message instanceof NewSession) {
NewSession newSession = (NewSession) message;
Log.w(TAG, "Received NewSessionCreated");
// Clearing pending acks because of session die
pendingConfirm.clear();
confirm.clear();
// Resending all required messages
ArrayList<ProtoMessage> toSend = new ArrayList<>();
for (ProtoMessage unsentPackage : unsentPackages.values()) {
if (unsentPackage.getMessageId() < newSession.getMessageId()) {
if (isEnableLog) {
Log.d(TAG, "ReSending #" + unsentPackage.getMessageId());
}
toSend.add(unsentPackage);
}
}
doSend(toSend);
} else if (message instanceof ReadPackageFromConnection) {
// Clearing pending confirmation
if (pendingConfirm.size() > 0) {
pendingConfirm.clear();
}
}
}
use of im.actor.core.network.mtp.entity.ProtoMessage in project actor-platform by actorapp.
the class ReceiverActor method onReceive.
private void onReceive(ProtoMessage message) {
sender.send(new PusherActor.ReadPackageFromConnection());
boolean disableConfirm = false;
try {
if (receivedMessages.size() >= MAX_RECEIVED_BUFFER) {
receivedMessages.remove(0);
}
receivedMessages.add(message.getMessageId());
ProtoStruct obj;
try {
obj = ProtoSerializer.readMessagePayload(message.getPayload());
} catch (IOException e) {
Log.w(TAG, "Unable to parse message: ignoring");
e.printStackTrace();
return;
}
if (obj instanceof NewSessionCreated) {
NewSessionCreated newSessionCreated = (NewSessionCreated) obj;
sender.send(new PusherActor.NewSession(newSessionCreated.getMessageId()));
proto.getCallback().onSessionCreated();
} else if (obj instanceof Container) {
Container container = (Container) obj;
for (ProtoMessage m : container.getMessages()) {
self().send(m, sender());
}
} else if (obj instanceof SessionLost) {
sender.send(new PusherActor.SessionLost());
} else if (obj instanceof MTRpcResponse) {
MTRpcResponse responseBox = (MTRpcResponse) obj;
// Forget messages
sender.send(new PusherActor.ForgetMessage(responseBox.getMessageId(), true));
proto.getCallback().onRpcResponse(responseBox.getMessageId(), responseBox.getPayload());
} else if (obj instanceof MessageAck) {
MessageAck ack = (MessageAck) obj;
for (long ackMsgId : ack.messagesIds) {
sender.send(new PusherActor.ForgetMessage(ackMsgId, false));
}
} else if (obj instanceof MTPush) {
MTPush box = (MTPush) obj;
proto.getCallback().onUpdate(box.getPayload());
} else if (obj instanceof UnsentResponse) {
UnsentResponse unsent = (UnsentResponse) obj;
if (!receivedMessages.contains(unsent.getResponseMessageId())) {
disableConfirm = true;
sender.send(new PusherActor.SendMessage(MTUids.nextId(), new RequestResend(unsent.getMessageId()).toByteArray(), true));
}
} else if (obj instanceof UnsentMessage) {
UnsentMessage unsent = (UnsentMessage) obj;
if (!receivedMessages.contains(unsent.getMessageId())) {
disableConfirm = true;
sender.send(new PusherActor.SendMessage(MTUids.nextId(), new RequestResend(unsent.getMessageId()).toByteArray(), false));
}
} else if (obj instanceof AuthIdInvalid) {
proto.getCallback().onAuthKeyInvalidated(proto.getAuthId());
proto.stopProto();
} else {
Log.w(TAG, "Unsupported package " + obj);
}
} catch (Exception e) {
Log.w(TAG, "Parsing error");
} finally {
if (!disableConfirm) {
sender.send(new PusherActor.ConfirmMessage(message.getMessageId()));
}
}
}
use of im.actor.core.network.mtp.entity.ProtoMessage in project actor-platform by actorapp.
the class AuthKeyActor method onConnectionStarted.
//
// Message Processing
//
private void onConnectionStarted() {
try {
if (currentState == null) {
throw new IOException();
}
ProtoStruct struct = currentState.sendStartMessage();
byte[] data = new ProtoPackage(0, 0, new ProtoMessage(0, struct.toByteArray())).toByteArray();
connection.post(data, 0, data.length);
} catch (Exception e) {
e.printStackTrace();
crashConnection();
}
}
use of im.actor.core.network.mtp.entity.ProtoMessage in project actor-platform by actorapp.
the class AuthKeyActor method goToState.
private void goToState(ActorState state) {
currentState = state;
if (connection != null) {
try {
ProtoStruct struct = currentState.sendStartMessage();
byte[] data = new ProtoPackage(0, 0, new ProtoMessage(0, struct.toByteArray())).toByteArray();
connection.post(data, 0, data.length);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Aggregations