Refactor code so that messages go through engines
Use state functions for message flow

The patch makes the code somewhat simpler and prepares it for
more complex initialization handshakes.