Search in sources :

Example 1 with ProtoMessage

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();
    }
}
Also used : DataInput(im.actor.runtime.bser.DataInput) EncryptedPackage(im.actor.core.network.mtp.entity.EncryptedPackage) ProtoMessage(im.actor.core.network.mtp.entity.ProtoMessage) EncryptedCBCPackage(im.actor.core.network.mtp.entity.EncryptedCBCPackage) IOException(java.io.IOException) IOException(java.io.IOException) AutoreleasePool(com.google.j2objc.annotations.AutoreleasePool)

Example 2 with ProtoMessage

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();
        }
    }
}
Also used : ProtoMessage(im.actor.core.network.mtp.entity.ProtoMessage) SessionHello(im.actor.core.network.mtp.entity.SessionHello) ArrayList(java.util.ArrayList) MessageAck(im.actor.core.network.mtp.entity.MessageAck)

Example 3 with ProtoMessage

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()));
        }
    }
}
Also used : MTRpcResponse(im.actor.core.network.mtp.entity.MTRpcResponse) MTPush(im.actor.core.network.mtp.entity.MTPush) NewSessionCreated(im.actor.core.network.mtp.entity.NewSessionCreated) Container(im.actor.core.network.mtp.entity.Container) ProtoStruct(im.actor.core.network.mtp.entity.ProtoStruct) AuthIdInvalid(im.actor.core.network.mtp.entity.AuthIdInvalid) ProtoMessage(im.actor.core.network.mtp.entity.ProtoMessage) UnsentResponse(im.actor.core.network.mtp.entity.UnsentResponse) MessageAck(im.actor.core.network.mtp.entity.MessageAck) UnsentMessage(im.actor.core.network.mtp.entity.UnsentMessage) IOException(java.io.IOException) IOException(java.io.IOException) RequestResend(im.actor.core.network.mtp.entity.RequestResend) SessionLost(im.actor.core.network.mtp.entity.SessionLost)

Example 4 with ProtoMessage

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();
    }
}
Also used : ProtoStruct(im.actor.core.network.mtp.entity.ProtoStruct) ProtoMessage(im.actor.core.network.mtp.entity.ProtoMessage) IOException(java.io.IOException) ProtoPackage(im.actor.core.network.mtp.entity.ProtoPackage) IOException(java.io.IOException)

Example 5 with ProtoMessage

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();
        }
    }
}
Also used : ProtoStruct(im.actor.core.network.mtp.entity.ProtoStruct) ProtoMessage(im.actor.core.network.mtp.entity.ProtoMessage) ProtoPackage(im.actor.core.network.mtp.entity.ProtoPackage) IOException(java.io.IOException)

Aggregations

ProtoMessage (im.actor.core.network.mtp.entity.ProtoMessage)5 IOException (java.io.IOException)4 ProtoStruct (im.actor.core.network.mtp.entity.ProtoStruct)3 MessageAck (im.actor.core.network.mtp.entity.MessageAck)2 ProtoPackage (im.actor.core.network.mtp.entity.ProtoPackage)2 AutoreleasePool (com.google.j2objc.annotations.AutoreleasePool)1 AuthIdInvalid (im.actor.core.network.mtp.entity.AuthIdInvalid)1 Container (im.actor.core.network.mtp.entity.Container)1 EncryptedCBCPackage (im.actor.core.network.mtp.entity.EncryptedCBCPackage)1 EncryptedPackage (im.actor.core.network.mtp.entity.EncryptedPackage)1 MTPush (im.actor.core.network.mtp.entity.MTPush)1 MTRpcResponse (im.actor.core.network.mtp.entity.MTRpcResponse)1 NewSessionCreated (im.actor.core.network.mtp.entity.NewSessionCreated)1 RequestResend (im.actor.core.network.mtp.entity.RequestResend)1 SessionHello (im.actor.core.network.mtp.entity.SessionHello)1 SessionLost (im.actor.core.network.mtp.entity.SessionLost)1 UnsentMessage (im.actor.core.network.mtp.entity.UnsentMessage)1 UnsentResponse (im.actor.core.network.mtp.entity.UnsentResponse)1 DataInput (im.actor.runtime.bser.DataInput)1 ArrayList (java.util.ArrayList)1