diff --git a/jni/libzrtp/sources/src/ZrtpStateClass.cpp b/jni/libzrtp/sources/src/ZrtpStateClass.cpp
new file mode 100644
index 0000000..f77f9f9
--- /dev/null
+++ b/jni/libzrtp/sources/src/ZrtpStateClass.cpp
@@ -0,0 +1,1471 @@
+/*
+  Copyright (C) 2006-2008 Werner Dittmann
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @author Werner Dittmann <Werner.Dittmann@t-online.de>
+ */
+
+#include <iostream>
+#include <cstdlib>
+#include <ctype.h>
+
+#include <libzrtpcpp/ZRtp.h>
+#include <libzrtpcpp/ZrtpStateClass.h>
+
+using namespace std;
+using namespace GnuZrtpCodes;
+
+state_t states[numberOfStates] = {
+    {Initial,      &ZrtpStateClass::evInitial },
+    {Detect,       &ZrtpStateClass::evDetect },
+    {AckDetected,  &ZrtpStateClass::evAckDetected },
+    {AckSent,      &ZrtpStateClass::evAckSent },
+    {WaitCommit,   &ZrtpStateClass::evWaitCommit },
+    {CommitSent,   &ZrtpStateClass::evCommitSent },
+    {WaitDHPart2,  &ZrtpStateClass::evWaitDHPart2 },
+    {WaitConfirm1, &ZrtpStateClass::evWaitConfirm1 },
+    {WaitConfirm2, &ZrtpStateClass::evWaitConfirm2 },
+    {WaitConfAck,  &ZrtpStateClass::evWaitConfAck },
+    {WaitClearAck, &ZrtpStateClass::evWaitClearAck },
+    {SecureState,  &ZrtpStateClass::evSecureState },
+    {WaitErrorAck, &ZrtpStateClass::evWaitErrorAck }
+};
+
+
+ZrtpStateClass::ZrtpStateClass(ZRtp *p) {
+    parent = p;
+    secSubstate = Normal;
+    engine = new ZrtpStates(states, numberOfStates, Initial);
+
+    commitPkt = NULL;
+    multiStream = false;
+
+    // Set up timers according to ZRTP spec
+    T1.start = 50;
+    T1.maxResend = 20;
+    T1.capping = 200;
+
+    T2.start = 150;
+    T2.maxResend = 10;
+    T2.capping = 600;
+}
+
+ZrtpStateClass::~ZrtpStateClass(void) {
+
+    // If not in Initial state: close the protocol engine
+    // before destroying it. This will free pending packets
+    // if necessary.
+    if (!inState(Initial)) {
+        Event_t ev;
+
+        cancelTimer();
+        ev.type = ZrtpClose;
+        event = &ev;
+        engine->processEvent(*this);
+    }
+    delete engine;
+}
+
+void ZrtpStateClass::processEvent(Event_t *ev) {
+
+    event = ev;
+    char *msg, first, middle, last;
+    uint8_t *pkt;
+
+    parent->synchEnter();
+
+    if (event->type == ZrtpPacket) {
+	pkt = event->packet;
+	msg = (char *)pkt + 4;
+	first = tolower(*msg);
+	middle = tolower(*(msg+4));
+        last = tolower(*(msg+7));
+
+        // Check if this is an Error packet.
+	if (first == 'e' && middle =='r' && last == ' ') {
+            /*
+             * Process a received Error packet.
+             *
+             * In any case stop timer to prevent resending packets.
+             * Use callback method to prepare and get an ErrorAck packet.
+             * Modify event type to "ErrorPkt" and hand it over to current
+             * state for further processing.
+             */
+            cancelTimer();
+            ZrtpPacketError epkt(pkt);
+            ZrtpPacketErrorAck* eapkt = parent->prepareErrorAck(&epkt);
+            parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(eapkt));
+            event->type = ErrorPkt;
+        }
+        else if (first == 'p' && middle == ' ' && last == ' ') {
+            ZrtpPacketPing ppkt(pkt);
+            ZrtpPacketPingAck* ppktAck = parent->preparePingAck(&ppkt);
+            parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(ppktAck));
+            parent->synchLeave();
+            return;
+        }
+        else if (first == 's' && last == 'y') {
+            uint32_t errorCode = 0;
+            ZrtpPacketSASrelay* srly = new ZrtpPacketSASrelay(pkt);
+            ZrtpPacketRelayAck* rapkt = parent->prepareRelayAck(srly, &errorCode);
+            parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(rapkt));
+            parent->synchLeave();
+            return;
+        }
+
+    }
+    /*
+     * Shut down protocol state engine: cancel outstanding timer, further
+     * processing in current state.
+     */
+    else if (event->type == ZrtpClose) {
+        cancelTimer();
+    }
+    engine->processEvent(*this);
+    parent->synchLeave();
+}
+
+
+void ZrtpStateClass::evInitial(void) {
+    DEBUGOUT((cout << "Checking for match in Initial.\n"));
+
+    if (event->type == ZrtpInitial) {
+	ZrtpPacketHello* hello = parent->prepareHello();
+
+	// remember packet for easy resend in case timer triggers
+	sentPacket = static_cast<ZrtpPacketBase *>(hello);
+
+        if (!parent->sendPacketZRTP(sentPacket)) {
+            sendFailed();                 // returns to state Initial
+            return;
+        }
+        if (startTimer(&T1) <= 0) {
+            timerFailed(SevereNoTimer);      // returns to state Initial
+            return;
+        }
+	nextState(Detect);
+    }
+}
+
+/*
+ * Detect state.
+ *
+ * When in this state the protocol engine sent an initial Hello packet
+ * to the peer.
+ *
+ * When entering this state transition function then:
+ * - Assume Initiator mode, mode may change later on peer reaction
+ * - Instance variable sentPacket contains the sent Hello packet
+ * - Hello timer T1 may be active. This is the case if the other peer
+ *   has prepared its RTP session and answers our Hello packets nearly 
+ *   immediately, i.e. before the Hello timeout counter expires. If the
+ *   other peer does not send a Hello during this time the state engine
+ *   reports "other peer does not support ZRTP" but stays
+ *   in state Detect with no active timer (passiv mode). Staying in state 
+ *   Detect allows another peer to start its detect phase any time later.
+ *
+ *   This restart capability is the reason why we use "startTimer(&T1)" in 
+ *   case we received a Hello packet from another peer. This effectively 
+ *   restarts the Hello timeout counter.
+ *
+ *   In this state we also handle ZrtpInitialize event. This forces a
+ *   restart of ZRTP discovery if an application calls ZrtpQueue#startZrtp
+ *   again. This may happen after a previous discovery phase were not 
+ *   successful.
+ *
+ *   Usually applications use some sort of signaling protocol, for example
+ *   SIP, to negotiate the RTP parameters. Thus the RTP sessions setup is
+ *   fairly sychronized and thus also the ZRTP detection phase. Applications
+ *   that use some other ways to setup the RTP sessions this restart capability
+ *   comes in handy because no RTP setup sychronization is necessary.
+ * 
+ * Possible events in this state are:
+ * - timeout for sent Hello packet: causes a resend check and 
+ *   repeat sending of Hello packet
+ * - received a HelloAck: stop active timer, prepare and send Hello packet,
+ *   switch to state AckDeteced.
+ * - received a Hello: stop active timer, send HelloAck, prepare Commit 
+ *   packet, switch to state AckSent.
+ *
+ */
+void ZrtpStateClass::evDetect(void) {
+
+    DEBUGOUT((cout << "Checking for match in Detect.\n"));
+
+    char *msg, first, last;
+    uint8_t *pkt;
+    uint32_t errorCode = 0;
+
+    /*
+     * First check the general event type, then discrimnate
+     * the real event.
+     */
+    if (event->type == ZrtpPacket) {
+        pkt = event->packet;
+        msg = (char *)pkt + 4;
+
+        first = tolower(*msg);
+        last = tolower(*(msg+7));
+        /*
+         * HelloAck:
+         * - our peer acknowledged our Hello packet, we have not seen the peer's Hello yet
+         * - cancel timer T1 to stop resending Hello
+         * - switch to state AckDetected, wait for peer's Hello (F3)
+         */
+        if (first == 'h' && last =='k') {
+            cancelTimer();
+            sentPacket = NULL;
+            nextState(AckDetected);
+            return;
+        }
+        /*
+         * Hello:
+         * - send HelloAck packet to acknowledge the received Hello packet 
+         * - use received Hello packet to prepare own Commit packet. We need to
+         *   do it at this point because we need the hash value computed from
+         *   peer's Hello packet. Follwing states my use the prepared Commit.
+         * - switch to new state AckSent which sends own Hello packet until 
+         *   peer acknowledges this
+         * - Don't clear sentPacket, points to Hello
+         */
+        if (first == 'h' && last ==' ') {
+            cancelTimer();
+            ZrtpPacketHelloAck* helloAck = parent->prepareHelloAck();
+
+            if (!parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(helloAck))) {
+                parent->zrtpNegotiationFailed(Severe, SevereCannotSend);
+                return;
+            }
+            // Use peer's Hello packet to create my commit packet, store it 
+            // for possible later usage in state AckSent
+            ZrtpPacketHello hpkt(pkt);
+            commitPkt = parent->prepareCommit(&hpkt, &errorCode);
+
+            nextState(AckSent);
+            if (commitPkt == NULL) {
+                sendErrorPacket(errorCode);    // switches to Error state
+                return;
+            }
+            if (startTimer(&T1) <= 0) {        // restart own Hello timer/counter
+                timerFailed(SevereNoTimer);    // returns to state Initial
+            }
+            T1.maxResend = 60;                 // more retries to extend time, see chap. 6
+        }
+        return;      // unknown packet for this state - Just ignore it
+    }
+    // Timer event triggered - this is Timer T1 to resend Hello
+    else if (event->type == Timer) {
+        if (!parent->sendPacketZRTP(sentPacket)) {
+            sendFailed();       // returns to state Initial
+            return;
+        }
+        if (nextTimer(&T1) <= 0) {
+            commitPkt = NULL;
+            parent->zrtpNotSuppOther();
+            nextState(Detect);
+        }
+    }
+    // If application call zrtpStart() to restart discovery
+    else if (event->type == ZrtpInitial) {
+        cancelTimer();
+        if (!parent->sendPacketZRTP(sentPacket)) {
+            sendFailed();                 // returns to state Initial
+            return;
+        }
+        if (startTimer(&T1) <= 0) {
+            timerFailed(SevereNoTimer);   // returns to state Initial
+        }
+    }
+    else { // unknown Event type for this state (covers Error and ZrtpClose)
+        if (event->type != ZrtpClose) {
+            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
+        }
+        sentPacket = NULL;
+        nextState(Initial);
+    }
+}
+
+/*
+ * AckSent state.
+ *
+ * The protocol engine got a Hello packet from peer and answered with a
+ * HelloAck response.  According to the protocol we must also send a 
+ * Hello after HelloAck (refer to figure 1 in ZRTP RFC xxxx, message 
+ * HelloACK (F2) must be followed by Hello (F3)). We use the timeout in 
+ * this state to send the required Hello (F3).
+ *
+ * Our peer must acknowledge the Hello with HelloAck. In earlier versions 
+ * also a Commit was a valid packet thus the code covers this.
+ * Figure 1 in the RFC shows the HelloAck, chapter 7 states that a Commit 
+ * may be send to acknowledge Hello. There is one constraint when using a Commit to
+ * acknowledge Hello: refer to chapter 4.1 that requires that both parties
+ * have completed the Hello/HelloAck discovery handshake. This implies that 
+ * only message F4 may be replaced by a Commit. This constraint guarantees
+ * that both peers have seen at least one Hello.
+ *
+ * When entering this transition function:
+ * - The instance variabe sentPacket contains own Hello packet
+ * - The instance variabe commitPkt points to prepared Commit packet 
+ * - Timer T1 is active
+ *
+ * Possible events in this state are:
+ * - timeout for sent Hello packet: causes a resend check and repeat sending
+ *   of Hello packet
+ * - HelloAck: The peer answered with HelloAck to own HelloAck/Hello. Send
+ *   prepared Commit packet and try Initiator mode.
+ * - Commit: The peer answered with Commit to HelloAck/Hello, thus switch to
+ *   responder mode.
+ * - Hello: If the protcol engine receives another Hello it repeats the 
+ *   HelloAck/Hello response until Timer T1 exceeds its maximum. This may 
+ *   happen if the other peer sends Hello only (maybe due to network problems)
+ */
+void ZrtpStateClass::evAckSent(void) {
+
+    DEBUGOUT((cout << "Checking for match in AckSent.\n"));
+
+    char *msg, first, last;
+    uint8_t *pkt;
+    uint32_t errorCode = 0;
+
+    /*
+     * First check the general event type, then discrimnate
+     * the real event.
+     */
+    if (event->type == ZrtpPacket) {
+        pkt = event->packet;
+	msg = (char *)pkt + 4;
+
+	first = tolower(*msg);
+	last = tolower(*(msg+7));
+
+	/*
+         * HelloAck:
+         * The peer answers with HelloAck to own HelloAck/Hello. Send Commit
+         * and try Initiator mode. The requirement defined in chapter 4.1 to
+         * have a complete Hello/HelloAck is fulfilled.
+	 * - stop Hello timer T1
+	 * - send own Commit message
+	 * - switch state to CommitSent, start Commit timer, assume Initiator
+	 */
+	if (first == 'h' && last =='k') {
+	    cancelTimer();
+
+            // remember packet for easy resend in case timer triggers
+            // Timer trigger received in new state CommitSend
+            sentPacket = static_cast<ZrtpPacketBase *>(commitPkt);
+            commitPkt = NULL;                    // now stored in sentPacket
+	    nextState(CommitSent);
+            if (!parent->sendPacketZRTP(sentPacket)) {
+                sendFailed();             // returns to state Initial
+                return;
+            }
+            if (startTimer(&T2) <= 0) {
+                timerFailed(SevereNoTimer);  // returns to state Initial
+	    }
+	    return;
+        }
+        /*
+         * Hello:
+         * - peer didn't receive our HelloAck
+         * - repeat HelloAck/Hello response:
+         *  -- get HelloAck packet, send it
+         *  -- The timeout trigger of T1 sends our Hello packet
+         *  -- stay in state AckSent
+         *
+         * Similar to Detect state: just acknowledge the Hello, the next
+         * timeout sends the following Hello.
+         */
+
+        if (first == 'h' && last ==' ') {
+            ZrtpPacketHelloAck* helloAck = parent->prepareHelloAck();
+
+            if (!parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(helloAck))) {
+                nextState(Detect);
+                parent->zrtpNegotiationFailed(Severe, SevereCannotSend);
+            }
+            return;
+        }
+        /*
+         * Commit:
+         * The peer answers with Commit to HelloAck/Hello, thus switch to
+         * responder mode.
+         * - stop timer T1
+         * - prepare and send our DHPart1
+         * - switch to state WaitDHPart2 and wait for peer's DHPart2
+         * - don't start timer, we are responder
+         */
+        if (first == 'c') {
+            cancelTimer();
+            ZrtpPacketCommit cpkt(pkt);
+
+            if (!multiStream) {
+                ZrtpPacketDHPart* dhPart1 = parent->prepareDHPart1(&cpkt, &errorCode);
+
+                // Something went wrong during processing of the Commit packet
+                if (dhPart1 == NULL) {
+                    if (errorCode != IgnorePacket) {
+                        sendErrorPacket(errorCode);
+                    }
+                    return;
+                }
+                commitPkt = NULL;
+                sentPacket = static_cast<ZrtpPacketBase *>(dhPart1);
+                nextState(WaitDHPart2);
+            }
+            else {
+                ZrtpPacketConfirm* confirm = parent->prepareConfirm1MultiStream(&cpkt, &errorCode);
+
+                // Something went wrong during processing of the Commit packet
+                if (confirm == NULL) {
+                    if (errorCode != IgnorePacket) {
+                        sendErrorPacket(errorCode);
+                    }
+                    return;
+                }
+                sentPacket = static_cast<ZrtpPacketBase *>(confirm);
+                nextState(WaitConfirm2);
+            }
+            if (!parent->sendPacketZRTP(sentPacket)) {
+                sendFailed();      // returns to state Initial
+            }
+        }
+    }
+    /*
+     * Timer:
+     * - resend Hello packet, stay in state, restart timer until repeat 
+     *   counter triggers
+     * - if repeat counter triggers switch to state Detect, con't clear
+     *   sentPacket, Detect requires it to point to own Hello message
+     */
+    else if (event->type == Timer) {
+        if (!parent->sendPacketZRTP(sentPacket)) {
+            return sendFailed();      // returns to state Initial
+        }
+        if (nextTimer(&T1) <= 0) {
+            parent->zrtpNotSuppOther();
+            commitPkt = NULL;
+            // Stay in state Detect to be prepared get an hello from
+            // other peer any time later
+            nextState(Detect);
+        }
+    }
+    else {   // unknown Event type for this state (covers Error and ZrtpClose)
+        if (event->type != ZrtpClose) {
+            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
+        }
+        commitPkt = NULL;
+        sentPacket = NULL;
+        nextState(Initial);
+    }
+}
+/*
+ * AckDetected state.
+ *
+ * The protocol engine received a HelloAck in state Detect, thus the peer 
+ * acknowledged our the Hello. According to ZRT RFC xxxx our peer must send
+ * its Hello until our protocol engine sees it (refer also to comment for
+ * state AckSent). This protocol sequence gurantees that both peers got at
+ * least one Hello. 
+ *
+ * When entering this transition function
+ * - instance variable sentPacket is NULL, Hello timer stopped
+ *
+ * Possible events in this state are:
+ * Hello: we have to choices
+ *  1) we can acknowledge the peer's Hello with a HelloAck
+ *  2) we can acknowledge the peer's Hello with a Commit
+ *  Both choices are implemented and may be enabled by setting a compile
+ *  time #if (see code below). Currently we use choice 1) here because
+ *  it's more aligned to the ZRTP specification
+ */
+void ZrtpStateClass::evAckDetected(void) {
+
+    DEBUGOUT((cout << "Checking for match in AckDetected.\n"));
+
+    char *msg, first, last;
+    uint8_t *pkt;
+    uint32_t errorCode = 0;
+
+    if (event->type == ZrtpPacket) {
+        pkt = event->packet;
+        msg = (char *)pkt + 4;
+
+        first = tolower(*msg);
+        last = tolower(*(msg+7));
+
+#if 1
+        /*
+         * Implementation for choice 1)
+         * Hello:
+         * - Acknowledge peers Hello, sending HelloACK (F4)
+         * - switch to state WaitCommit, wait for peer's Commit
+         * - we are going to be in the Responder role
+         */
+
+        if (first == 'h' && last ==' ') {
+            // Parse Hello packet and build an own Commit packet even if the
+            // Commit is not send to the peer. We need to do this to check the
+            // Hello packet and prepare the shared secret stuff.
+            ZrtpPacketHello hpkt(pkt);
+            ZrtpPacketCommit* commit = parent->prepareCommit(&hpkt, &errorCode);
+
+            // Something went wrong during processing of the Hello packet, for
+            // example wrong version, duplicate ZID.
+            if (commit == NULL) {
+                sendErrorPacket(errorCode);
+                return;
+            }
+            ZrtpPacketHelloAck *helloAck = parent->prepareHelloAck();
+            nextState(WaitCommit);
+
+            // remember packet for easy resend
+            sentPacket = static_cast<ZrtpPacketBase *>(helloAck);
+            if (!parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(helloAck))) {
+                sendFailed();
+            }
+        }
+#else
+        /*
+         * Implementation for choice 2)
+         * Hello:
+         * - Acknowledge peers Hello by sending Commit (F5)
+         *   instead of HelloAck (F4)
+         * - switch to state CommitSent
+         * - Initiator role, thus start timer T2 to monitor timeout for Commit
+         */
+
+        if (first == 'h') {
+            // Parse peer's packet data into a Hello packet
+            ZrtpPacketHello hpkt(pkt);
+            ZrtpPacketCommit* commit = parent->prepareCommit(&hpkt, &errorCode);
+            // Something went wrong during processing of the Hello packet  
+            if (commit == NULL) {
+                sendErrorPacket(errorCode);
+                return;
+            }
+            nextState(CommitSent);
+
+            // remember packet for easy resend in case timer triggers
+            // Timer trigger received in new state CommitSend
+            sentPacket = static_cast<ZrtpPacketBase *>(commit);
+            if (!parent->sendPacketZRTP(sentPacket)) {
+                sendFailed();
+                return;
+            }
+            if (startTimer(&T2) <= 0) {
+                timerFailed(SevereNoTimer);
+            }
+        }
+#endif
+    }
+    else {  // unknown Event type for this state (covers Error and ZrtpClose)
+        if (event->type != ZrtpClose) {
+            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
+        }
+        nextState(Initial);
+    }
+}
+
+/*
+ * WaitCommit state.
+ *
+ * This state is only used if we use choice 1) in AckDetected.
+ *
+ * When entering this transition function
+ * - instance variable sentPacket contains a HelloAck packet
+ * 
+ * Possible events in this state are:
+ * - Hello: just resend our HelloAck
+ * - Commit: prepare and send our DHPart1 message to start first
+ *   half of DH key agreement. Switch to state WaitDHPart2, don't
+ *   start any timer, we a Responder.
+ */
+void ZrtpStateClass::evWaitCommit(void) {
+
+    DEBUGOUT((cout << "Checking for match in WaitCommit.\n"));
+
+    char *msg, first;
+    uint8_t *pkt;
+    uint32_t errorCode = 0;
+
+    if (event->type == ZrtpPacket) {
+        pkt = event->packet;
+        msg = (char *)pkt + 4;
+
+        first = tolower(*msg);
+        /*
+         * Hello:
+         * - resend HelloAck
+         * - stay in WaitCommit
+         */
+        if (first == 'h') {
+            if (!parent->sendPacketZRTP(sentPacket)) {
+                sendFailed();       // returns to state Initial
+            }
+            return;
+        }
+        /*
+         * Commit:
+         * - prepare DH1Part packet or Confirm1 if multi stream mode
+         * - send it to peer
+         * - switch state to WaitDHPart2 or WaitConfirm2 if multi stream mode
+         * - don't start timer, we are responder
+         */
+        if (first == 'c') {
+            ZrtpPacketCommit cpkt(pkt);
+
+            if (!multiStream) {
+                ZrtpPacketDHPart* dhPart1 = parent->prepareDHPart1(&cpkt, &errorCode);
+
+                // Something went wrong during processing of the Commit packet
+                if (dhPart1 == NULL) {
+                    if (errorCode != IgnorePacket) {
+                        sendErrorPacket(errorCode);
+                    }
+                    return;
+                }
+                sentPacket = static_cast<ZrtpPacketBase *>(dhPart1);
+                nextState(WaitDHPart2);
+            }
+            else {
+                ZrtpPacketConfirm* confirm = parent->prepareConfirm1MultiStream(&cpkt, &errorCode);
+
+                // Something went wrong during processing of the Commit packet
+                if (confirm == NULL) {
+                    if (errorCode != IgnorePacket) {
+                        sendErrorPacket(errorCode);
+                    }
+                    return;
+                }
+                sentPacket = static_cast<ZrtpPacketBase *>(confirm);
+                nextState(WaitConfirm2);
+            }
+            if (!parent->sendPacketZRTP(sentPacket)) {
+                sendFailed();       // returns to state Initial
+            }
+        }
+    }
+    else {  // unknown Event type for this state (covers Error and ZrtpClose)
+        if (event->type != ZrtpClose) {
+            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
+        }
+        sentPacket = NULL;
+        nextState(Initial);
+    }
+}
+
+/*
+ * CommitSent state.
+ *
+ * This state either handles a DH1Part1 message to start the first
+ * half of DH key agreement or it handles a Commit clash. If handling a
+ * Commit clash it may happen that we change our role from Initiator to
+ * Responder.
+ *
+ * When entering this transition function
+ * - assume Initiator mode, may change if we reveice a Commit here
+ * - sentPacket contains Commit packet
+ * - Commit timer (T2) active
+ *
+ * Possible events in this state are:
+ * - timeout for sent Commit packet: causes a resend check and repeat sending
+ *   of Commit packet
+ * - Commit: This is a Commit clash. Break the tie accroding to chapter 5.2
+ * - DHPart1: start first half of DH key agreement. Perpare and send own DHPart2
+ *   and switch to state WaitConfirm1.
+ */
+
+void ZrtpStateClass::evCommitSent(void) {
+
+    DEBUGOUT((cout << "Checking for match in CommitSend.\n"));
+
+    char *msg, first, last;
+    uint8_t *pkt;
+    uint32_t errorCode = 0;
+
+    if (event->type == ZrtpPacket) {
+        pkt = event->packet;
+        msg = (char *)pkt + 4;
+
+        first = tolower(*msg);
+        last = tolower(*(msg+7));
+
+        /*
+         * HelloAck or Hello:
+         * - delayed "HelloAck" or "Hello", maybe due to network latency, just 
+         *   ignore it
+         * - no switch in state, leave timer as it is
+         */
+        if (first == 'h' && (last =='k' || last == ' ')) {
+            return;
+        }
+
+        /*
+         * Commit:
+         * We have a "Commit" clash. Resolve it.
+         *
+         * - switch off resending Commit
+         * - compare my hvi with peer's hvi
+         * - if my hvi is greater
+         *   - we are Initiator, stay in state, wait for peer's DHPart1 packet
+         * - else
+         *   - we are Responder, stop timer
+         *   - prepare and send DH1Packt,
+         *   - switch to state WaitDHPart2, implies Responder path
+         */
+        if (first == 'c' && last == ' ') {
+            ZrtpPacketCommit zpCo(pkt);
+
+            if (!parent->verifyH2(&zpCo)) {
+                return;
+            }
+            cancelTimer();         // this cancels the Commit timer T2
+
+            // if our hvi is less than peer's hvi: switch to Responder mode and
+            // send DHPart1 or Confirm1 packet. Peer (as Initiator) will retrigger if
+            // necessary
+            //
+            if (parent->compareCommit(&zpCo) < 0) {
+                if (!multiStream) {
+                    ZrtpPacketDHPart* dhPart1 = parent->prepareDHPart1(&zpCo, &errorCode);
+
+                    // Something went wrong during processing of the Commit packet
+                    if (dhPart1 == NULL) {
+                        if (errorCode != IgnorePacket) {
+                            sendErrorPacket(errorCode);
+                        }
+                        return;
+                    }
+                    nextState(WaitDHPart2);
+                    sentPacket = static_cast<ZrtpPacketBase *>(dhPart1);
+                }
+                else {
+                    ZrtpPacketConfirm* confirm = parent->prepareConfirm1MultiStream(&zpCo, &errorCode);
+
+                    // Something went wrong during processing of the Commit packet
+                    if (confirm == NULL) {
+                        if (errorCode != IgnorePacket) {
+                            sendErrorPacket(errorCode);
+                        }
+                        return;
+                    }
+                    nextState(WaitConfirm2);
+                    sentPacket = static_cast<ZrtpPacketBase *>(confirm);
+                }
+                if (!parent->sendPacketZRTP(sentPacket)) {
+                    sendFailed();       // returns to state Initial
+                }
+            }
+            // Stay in state, we are Initiator, wait for DHPart1 of Confirm1 packet from peer.
+            // Resend Commit after timeout until we get a DHPart1 or Confirm1
+            else {
+                if (startTimer(&T2) <= 0) { // restart the Commit timer, gives peer more time to react
+                    timerFailed(SevereNoTimer);    // returns to state Initial
+                }
+            }
+            return;
+        }
+
+        /*
+         * DHPart1:
+         * - switch off resending Commit
+         * - Prepare and send DHPart2
+         * - switch to WaitConfirm1
+         * - start timer to resend DHPart2 if necessary, we are Initiator
+         */
+        if (first == 'd') {
+            cancelTimer();
+            sentPacket = NULL;
+            ZrtpPacketDHPart dpkt(pkt);
+            ZrtpPacketDHPart* dhPart2 = parent->prepareDHPart2(&dpkt, &errorCode);
+
+            // Something went wrong during processing of the DHPart1 packet
+            if (dhPart2 == NULL) {
+                if (errorCode != IgnorePacket) {
+                    sendErrorPacket(errorCode);
+                }
+                else {
+                    if (startTimer(&T2) <= 0) {
+                        timerFailed(SevereNoTimer);       // switches to state Initial
+                    }
+                }
+
+                return;
+            }
+            sentPacket = static_cast<ZrtpPacketBase *>(dhPart2);
+            nextState(WaitConfirm1);
+
+            if (!parent->sendPacketZRTP(sentPacket)) {
+                sendFailed();       // returns to state Initial
+                return;
+            }
+            if (startTimer(&T2) <= 0) {
+                timerFailed(SevereNoTimer);       // switches to state Initial
+            }
+            return;
+        }
+
+        if (multiStream && (first == 'c' && last == '1')) {
+            cancelTimer();
+            ZrtpPacketConfirm cpkt(pkt);
+
+            ZrtpPacketConfirm* confirm = parent->prepareConfirm2MultiStream(&cpkt, &errorCode);
+
+            // Something went wrong during processing of the Confirm1 packet
+            if (confirm == NULL) {
+                sendErrorPacket(errorCode);
+                return;
+            }
+            nextState(WaitConfAck);
+            sentPacket = static_cast<ZrtpPacketBase *>(confirm);
+
+            if (!parent->sendPacketZRTP(sentPacket)) {
+                sendFailed();         // returns to state Initial
+                return;
+            }
+            if (startTimer(&T2) <= 0) {
+                timerFailed(SevereNoTimer);  // returns to state Initial
+                return;
+            }
+            // according to chap 5.6: after sending Confirm2 the Initiator must
+            // be ready to receive SRTP data. SRTP sender will be enabled in WaitConfAck
+            // state.
+            if (!parent->srtpSecretsReady(ForReceiver)) {
+                parent->sendInfo(Severe, CriticalSWError);
+                sendErrorPacket(CriticalSWError);
+                return;
+            }
+        }
+    }
+    // Timer event triggered, resend the Commit packet
+    else if (event->type == Timer) {
+        if (!parent->sendPacketZRTP(sentPacket)) {
+                sendFailed();       // returns to state Initial
+                return;
+        }
+        if (nextTimer(&T2) <= 0) {
+            timerFailed(SevereTooMuchRetries);       // returns to state Initial
+        }
+    }
+    else {  // unknown Event type for this state (covers Error and ZrtpClose)
+        if (event->type != ZrtpClose) {
+            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
+        }
+        sentPacket = NULL;
+        nextState(Initial);
+    }
+}
+
+/*
+ * WaitDHPart2 state.
+ *
+ * This state handles the second part of SH key agreement. Only the Resonder
+ * can enter this state.
+ *
+ * When entering this transition function
+ * - sentPacket contains DHPart1 packet, no timer active
+ *
+ * Possible events in this state are:
+ * - Commit: Our peer didn't receive out DHPart1 thus the peer sends Commit again.
+ *   Just repeat our DHPart1.
+ * - DHPart2: start second half of DH key agreement. Perpare and send own Confirm1
+ *   and switch to state WaitConfirm2.
+ */
+void ZrtpStateClass::evWaitDHPart2(void) {
+
+    DEBUGOUT((cout << "Checking for match in DHPart2.\n"));
+
+    char *msg, first;
+    uint8_t *pkt;
+    uint32_t errorCode = 0;
+
+    if (event->type == ZrtpPacket) {
+        pkt = event->packet;
+        msg = (char *)pkt + 4;
+
+        first = tolower(*msg);
+        /*
+         * Commit:
+         * - resend DHPart1
+         * - stay in state
+         */
+        if (first == 'c') {
+            if (!parent->sendPacketZRTP(sentPacket)) {
+                return sendFailed();       // returns to state Initial
+            }
+            return;
+        }
+        /*
+         * DHPart2:
+         * - prepare Confirm1 packet
+         * - switch to WaitConfirm2
+         * - No timer, we are responder
+         */
+        if (first == 'd') {
+            ZrtpPacketDHPart dpkt(pkt);
+            ZrtpPacketConfirm* confirm = parent->prepareConfirm1(&dpkt, &errorCode);
+
+            if (confirm == NULL) {
+                if (errorCode != IgnorePacket) {
+                    sendErrorPacket(errorCode);
+                }
+                return;
+            }
+            nextState(WaitConfirm2);
+            sentPacket = static_cast<ZrtpPacketBase *>(confirm);
+            if (!parent->sendPacketZRTP(sentPacket)) {
+                sendFailed();       // returns to state Initial
+            }
+        }
+    }
+    else {  // unknown Event type for this state (covers Error and ZrtpClose)
+        if (event->type != ZrtpClose) {
+            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
+        }
+        sentPacket = NULL;
+        nextState(Initial);
+    }
+}
+
+/*
+ * WaitConirm1 state.
+ *
+ * This state handles a received Confirm1 message and only the Initiator
+ * can enter this state.
+ *
+ * When entering this transition function in DH mode:
+ * - Initiator mode
+ * - sentPacket contains DHPart2 packet, DHPart2 timer active
+ *
+ * When entering this transition function in Multi stream mode via AckSent:
+ * - Initiator mode
+ * - sentPacket contains my Commit packet, Commit timer active
+ * 
+* Possible events in this state are:
+ * - timeout for sent DHPart2 packet: causes a resend check and repeat sending
+ *   of DHPart2 packet.
+ * - Confirm1: Check Confirm1 message. If it is ok then prepare and send own
+ *   Confirm2 packet and switch to state WaitConfAck.
+ */
+void ZrtpStateClass::evWaitConfirm1(void) {
+
+    DEBUGOUT((cout << "Checking for match in WaitConfirm1.\n"));
+
+    char *msg, first, last;
+    uint8_t *pkt;
+    uint32_t errorCode = 0;
+
+    if (event->type == ZrtpPacket) {
+        pkt = event->packet;
+        msg = (char *)pkt + 4;
+
+        first = tolower(*msg);
+        last = tolower(*(msg+7));
+
+        /*
+         * Confirm1:
+         * - Switch off resending DHPart2
+         * - prepare a Confirm2 packet
+         * - switch to state WaitConfAck
+         * - set timer to monitor Confirm2 packet, we are initiator
+         */
+        if (first == 'c' && last == '1') {
+            cancelTimer();
+            ZrtpPacketConfirm cpkt(pkt);
+
+            ZrtpPacketConfirm* confirm = parent->prepareConfirm2(&cpkt, &errorCode);
+
+            // Something went wrong during processing of the Confirm1 packet
+            if (confirm == NULL) {
+                sendErrorPacket(errorCode);
+                return;
+            }
+            nextState(WaitConfAck);
+            sentPacket = static_cast<ZrtpPacketBase *>(confirm);
+
+            if (!parent->sendPacketZRTP(sentPacket)) {
+                sendFailed();         // returns to state Initial
+                return;
+            }
+            if (startTimer(&T2) <= 0) {
+                timerFailed(SevereNoTimer);  // returns to state Initial TODO check for return following this line
+            }
+            // according to chap 5.8: after sending Confirm2 the Initiator must
+            // be ready to receive SRTP data. SRTP sender will be enabled in WaitConfAck
+            // state.
+            if (!parent->srtpSecretsReady(ForReceiver)) {
+                parent->sendInfo(Severe, CriticalSWError);
+                sendErrorPacket(CriticalSWError);
+                return;
+            }
+        }
+    }
+    else if (event->type == Timer) {
+        if (!parent->sendPacketZRTP(sentPacket)) {
+            sendFailed();             // returns to state Initial
+            return;
+        }
+        if (nextTimer(&T2) <= 0) {
+            timerFailed(SevereTooMuchRetries);     // returns to state Initial
+        }
+    }
+    else {  // unknown Event type for this state (covers Error and ZrtpClose)
+        if (event->type != ZrtpClose) {
+            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
+        }
+        sentPacket = NULL;
+        nextState(Initial);
+    }
+}
+
+/*
+ * WaitConfirm2 state.
+ *
+ * Handles the Confirm2 message that closes the key agreement handshake. Only
+ * the Responder can enter this state. If the Confirm2 message is ok send a 
+ * Conf2Ack to our peer. Switch to secure mode after sending Conf2Ack, our 
+ * peer switches to secure mode after receiving Conf2Ack.
+ *
+ * TODO - revise documentation comments
+ * 
+ * When entering this transition function
+ * - Responder mode
+ * - sentPacket contains Confirm1 packet, no timer active
+ *
+ * Possible events in this state are:
+ * - DHPart2: Our peer didn't receive our Confirm1 thus sends DHPart2 again.
+ *   Just repeat our Confirm1.
+ * - Confirm2: close DH key agreement. Perpare and send own Conf2Ack
+ *   and switch to state SecureState.
+ */
+void ZrtpStateClass::evWaitConfirm2(void) {
+
+    DEBUGOUT((cout << "Checking for match in WaitConfirm2.\n"));
+
+    char *msg, first, last;
+    uint8_t *pkt;
+    uint32_t errorCode = 0;
+
+    if (event->type == ZrtpPacket) {
+        pkt = event->packet;
+        msg = (char *)pkt + 4;
+
+        first = tolower(*msg);
+        last = tolower(*(msg+7));
+
+        /*
+         * DHPart2 or Commit in multi stream mode:
+         * - resend Confirm1 packet
+         * - stay in state
+         */
+        if (first == 'd' || (multiStream && (first == 'c' && last == ' '))) {
+            if (!parent->sendPacketZRTP(sentPacket)) {
+                sendFailed();             // returns to state Initial
+            }
+            return;
+        }
+        /*
+         * Confirm2:
+         * - prepare ConfAck
+         * - switch on security (SRTP)
+         * - switch to SecureState
+         */
+        if (first == 'c' && last == '2') {
+            ZrtpPacketConfirm cpkt(pkt);
+            ZrtpPacketConf2Ack* confack = parent->prepareConf2Ack(&cpkt, &errorCode);
+
+            // Something went wrong during processing of the confirm2 packet
+            if (confack == NULL) {
+                sendErrorPacket(errorCode);
+                return;
+            }
+            sentPacket = static_cast<ZrtpPacketBase *>(confack);
+
+            if (!parent->sendPacketZRTP(sentPacket)) {
+                sendFailed();             // returns to state Initial
+                return;
+            }
+            if (!parent->srtpSecretsReady(ForSender) ||
+                !parent->srtpSecretsReady(ForReceiver)) {
+                parent->sendInfo(Severe, CriticalSWError);
+                sendErrorPacket(CriticalSWError);
+                return;
+            }
+            nextState(SecureState);
+            parent->sendInfo(Info, InfoSecureStateOn);
+        }
+    }
+    else {  // unknown Event type for this state (covers Error and ZrtpClose)
+        if (event->type != ZrtpClose) {
+            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
+        }
+        sentPacket = NULL;
+        nextState(Initial);
+    }
+}
+
+/*
+ * WaitConf2Ack state.
+ *
+ * This state handles the Conf2Ack message that acknowledges the successfull
+ * processing of Confirm2. Only the Initiator can enter this state. Switch on
+ * secure mode and switch to state SecureState.
+ *
+ * When entering this transition function
+ * - Initiator mode
+ * - sentPacket contains Confirm2 packet, Confirm2 timer active
+ * - receiver security switched on
+ *
+ * Possible events in this state are:
+ * - timeout for sent Confirm2 packet: causes a resend check and repeat sending
+ *   of Confirm2 packet
+ * - Conf2Ack: Key agreement was successfull, switch to secure mode.
+ */
+void ZrtpStateClass::evWaitConfAck(void) {
+
+    DEBUGOUT((cout << "Checking for match in WaitConfAck.\n"));
+
+    char *msg, first;
+    uint8_t *pkt;
+
+    if (event->type == ZrtpPacket) {
+        pkt = event->packet;
+        msg = (char *)pkt + 4;
+
+        first = tolower(*msg);
+         /*
+         * ConfAck:
+         * - Switch off resending Confirm2
+         * - switch to SecureState
+         */
+        if (first == 'c') {
+            cancelTimer();
+            sentPacket = NULL;
+            // Receiver was already enabled after sending Confirm2 packet
+            // see previous states.
+            if (!parent->srtpSecretsReady(ForSender)) {
+                parent->sendInfo(Severe, CriticalSWError);
+                sendErrorPacket(CriticalSWError);
+                return;
+            }
+            nextState(SecureState);
+            // TODO: call parent to clear signature data at initiator
+            parent->sendInfo(Info, InfoSecureStateOn);
+        }
+    }
+    else if (event->type == Timer) {
+        if (!parent->sendPacketZRTP(sentPacket)) {
+            sendFailed();             // returns to state Initial
+            parent->srtpSecretsOff(ForReceiver);
+            return;
+        }
+        if (nextTimer(&T2) <= 0) {
+            timerFailed(SevereTooMuchRetries); // returns to state Initial
+            parent->srtpSecretsOff(ForReceiver);
+        }
+    }
+    else {  // unknown Event type for this state (covers Error and ZrtpClose)
+        if (event->type != ZrtpClose) {
+            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
+        }
+        sentPacket = NULL;
+        nextState(Initial);
+        parent->srtpSecretsOff(ForReceiver);
+    }
+}
+
+/*
+ * When entering this transition function
+ * - sentPacket contains GoClear packet, GoClear timer active
+ */
+
+void ZrtpStateClass::evWaitClearAck(void) {
+    DEBUGOUT((cout << "Checking for match in ClearAck.\n"));
+
+    char *msg, first, last;
+    uint8_t *pkt;
+
+    if (event->type == ZrtpPacket) {
+	pkt = event->packet;
+	msg = (char *)pkt + 4;
+
+	first = tolower(*msg);
+	last = tolower(*(msg+7));
+
+	/*
+	 * ClearAck:
+	 * - stop resending GoClear,
+	 * - switch to state AckDetected, wait for peer's Hello
+	 */
+	if (first == 'c' && last =='k') {
+	    cancelTimer();
+	    sentPacket = NULL;
+	    nextState(Initial);
+	}
+    }
+    // Timer event triggered - this is Timer T2 to resend GoClear w/o HMAC
+    else if (event->type == Timer) {
+        if (!parent->sendPacketZRTP(sentPacket)) {
+            sendFailed();                 // returns to state Initial
+            return;
+        }
+        if (nextTimer(&T2) <= 0) {
+            timerFailed(SevereTooMuchRetries);     // returns to state Initial
+        }
+    }
+    else {  // unknown Event type for this state (covers Error and ZrtpClose)
+        if (event->type != ZrtpClose) {
+            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
+        }
+	sentPacket = NULL;
+	nextState(Initial);
+    }
+}
+
+
+/*
+ * WaitErrorAck state.
+ *
+ * This state belongs to the "error handling state overlay" and handle
+ * ErrorAck message. Most of the ZRTP states can send Error message for
+ * example if they detect wrong packets. After sending an Error message
+ * the protocol engine switches to WaitErrorAck state. Receiving an
+ * ErrorAck message completes the ZRTP error handling.
+ *
+ * When entering this transition function
+ * - sentPacket contains Error packet, Error timer active
+ *
+ * Possible events in this state are:
+ * - timeout for sent Error packet: causes a resend check and repeat sending
+ *   of Error packet
+ * - ErrorAck: Stop timer and switch to state Initial.
+ */
+
+void ZrtpStateClass::evWaitErrorAck(void) {
+    DEBUGOUT((cout << "Checking for match in ErrorAck.\n"));
+
+    char *msg, first, last;
+    uint8_t *pkt;
+
+    if (event->type == ZrtpPacket) {
+        pkt = event->packet;
+        msg = (char *)pkt + 4;
+
+        first = tolower(*msg);
+        last = tolower(*(msg+7));
+
+        /*
+         * Errorck:
+         * - stop resending Error,
+         * - switch to state Initial
+         */
+        if (first == 'e' && last =='k') {
+            cancelTimer();
+            sentPacket = NULL;
+            nextState(Initial);
+        }
+    }
+    // Timer event triggered - this is Timer T2 to resend Error.
+    else if (event->type == Timer) {
+        if (!parent->sendPacketZRTP(sentPacket)) {
+            sendFailed();                 // returns to state Initial
+            return;
+        }
+        if (nextTimer(&T2) <= 0) {
+            timerFailed(SevereTooMuchRetries);     // returns to state Initial
+        }
+    }
+    else {  // unknown Event type for this state (covers Error and ZrtpClose)
+        if (event->type != ZrtpClose) {
+            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
+        }
+        sentPacket = NULL;
+        nextState(Initial);
+    }
+}
+
+void ZrtpStateClass::evSecureState(void) {
+
+    DEBUGOUT((cout << "Checking for match in SecureState.\n"));
+
+    char *msg, first, last;
+    uint8_t *pkt;
+
+    /*
+     * Handle a possible substate. If substate handling was ok just return.
+     */
+    if (secSubstate == WaitSasRelayAck) {
+        if (subEvWaitRelayAck())
+            return; 
+    }
+
+    if (event->type == ZrtpPacket) {
+        pkt = event->packet;
+        msg = (char *)pkt + 4;
+
+        first = tolower(*msg);
+        last = tolower(*(msg+7));
+
+        /*
+         * Confirm2:
+         * - resend Conf2Ack packet
+         * - stay in state
+         */
+        if (first == 'c' && last == '2') {
+            if (sentPacket != NULL && !parent->sendPacketZRTP(sentPacket)) {
+                sentPacket = NULL;
+                nextState(Initial);
+                parent->srtpSecretsOff(ForSender);
+                parent->srtpSecretsOff(ForReceiver);
+                parent->zrtpNegotiationFailed(Severe, SevereCannotSend);
+            }
+            return;
+        }
+        /*
+         * GoClear received, handle it. TODO fix go clear handling
+         */
+        if (first == 'g' && last == 'r') {
+            ZrtpPacketGoClear gpkt(pkt);
+            ZrtpPacketClearAck* clearAck = parent->prepareClearAck(&gpkt);
+
+            if (!parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(clearAck))) {
+                return;
+            }
+        // TODO Timeout to resend clear ack until user user confirmation
+        }
+    }
+    else {  // unknown Event type for this state (covers Error and ZrtpClose)
+        sentPacket = NULL;
+        parent->srtpSecretsOff(ForSender);
+        parent->srtpSecretsOff(ForReceiver);
+        nextState(Initial);
+        if (event->type != ZrtpClose) {
+            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
+        }
+        parent->sendInfo(Info, InfoSecureStateOff);
+    }
+}
+
+bool ZrtpStateClass::subEvWaitRelayAck() {
+    char *msg, first, last;
+    uint8_t* pkt;
+
+    /*
+     * First check the general event type, then discrimnate the real event.
+     */
+    if  (event->type == ZrtpPacket) {
+        pkt = event->packet;
+        msg = (char *)pkt + 4;
+
+        first = tolower(*msg);
+        last = tolower(*(msg+7));
+
+        /*
+         * SAS relayAck:
+         * - stop resending SASRelay,
+         * - switch to secure substate Normal
+         */
+        if (first == 'r' && last =='k') {
+            cancelTimer();
+            secSubstate = Normal;
+            sentPacket = NULL;
+        }
+        return true;
+    }
+    // Timer event triggered - this is Timer T2 to resend Error.
+    else if (event->type == Timer) {
+        if (!parent->sendPacketZRTP(sentPacket)) {
+            sendFailed(); // returns to state Initial
+            return false;
+        }
+        if (nextTimer(&T2) <= 0) {
+            // returns to state initial
+            // timerFailed(ZrtpCodes.SevereCodes.SevereTooMuchRetries);
+            return false;
+        }
+        return true;
+    }
+    return false;
+}
+
+int32_t ZrtpStateClass::startTimer(zrtpTimer_t *t) {
+
+    t->time = t->start;
+    t->counter = 0;
+    return parent->activateTimer(t->time);
+}
+
+int32_t ZrtpStateClass::nextTimer(zrtpTimer_t *t) {
+
+    t->time += t->time;
+    t->time = (t->time > t->capping)? t->capping : t->time;
+    t->counter++;
+    if (t->counter > t->maxResend) {
+        return -1;
+    }
+    return parent->activateTimer(t->time);
+}
+
+void ZrtpStateClass::sendErrorPacket(uint32_t errorCode) {
+    cancelTimer();
+
+    ZrtpPacketError* err = parent->prepareError(errorCode);
+    parent->zrtpNegotiationFailed(ZrtpError, errorCode);
+
+    sentPacket =  static_cast<ZrtpPacketBase *>(err);
+    nextState(WaitErrorAck);
+    if (!parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(err)) || (startTimer(&T2) <= 0)) {
+        sendFailed();
+    }
+}
+
+void ZrtpStateClass::sendSASRelay(ZrtpPacketSASrelay* relay) {
+    cancelTimer();
+    sentPacket = static_cast<ZrtpPacketBase *>(relay);
+    secSubstate = WaitSasRelayAck;
+    if (!parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(relay)) || (startTimer(&T2) <= 0)) {
+        sendFailed();
+    }
+}
+
+void ZrtpStateClass::sendFailed() {
+    sentPacket = NULL;
+    nextState(Initial);
+    parent->zrtpNegotiationFailed(Severe, SevereCannotSend);
+}
+
+void ZrtpStateClass::timerFailed(int32_t subCode) {
+    sentPacket = NULL;
+    nextState(Initial);
+    parent->zrtpNegotiationFailed(Severe, subCode);
+}
+
+void ZrtpStateClass::setMultiStream(bool multi) {
+    multiStream = multi;
+}
+
+bool ZrtpStateClass::isMultiStream() {
+    return multiStream;
+}
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
