diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpQueue.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpQueue.h
new file mode 100644
index 0000000..7a1ee67
--- /dev/null
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpQueue.h
@@ -0,0 +1,911 @@
+/*
+  Copyright (C) 2006-2009 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/>.
+*/
+
+#ifndef _ZRTPQUEUE_H_
+#define _ZRTPQUEUE_H_
+
+#include <ccrtp/cqueue.h>
+#include <ccrtp/rtppkt.h>
+#include <libzrtpcpp/ZrtpCallback.h>
+#include <libzrtpcpp/ZrtpConfigure.h>
+#include <CcrtpTimeoutProvider.h>
+
+class __EXPORT ZrtpUserCallback;
+class __EXPORT ZRtp;
+
+NAMESPACE_COMMONCPP
+
+/**
+ * GNU ccRTP extension to support GNU ZRTP.
+ *
+ * ZRTP was developed by Phil Zimmermann and provides functions to
+ * negotiate keys and other necessary data (crypto data) to set-up
+ * the Secure RTP (SRTP) crypto context. Refer to Phil's ZRTP
+ * specification at his <a href="http://zfoneproject.com/">Zfone
+ * project</a> site to get more detailed imformation about the
+ * capabilities of ZRTP.
+ *
+ * <b>Short overview of the ZRTP implementation</b>
+ *
+ * ZRTP is a specific protocol to negotiate encryption algorithms
+ * and the required key material. ZRTP uses a RTP session to
+ * exchange its protocol messages.
+ *
+ * A complete GNU ZRTP implementation consists of two parts, the
+ * GNU ZRTP core and specific code that binds the GNU ZRTP core to
+ * the underlying RTP/SRTP stack and the operating system:
+ * <ul>
+ * <li>
+ *      The GNU ZRTP core is independent of a specific RTP/SRTP
+ *      stack and the operationg system and consists of the ZRTP
+ *      protocol state engine, the ZRTP protocol messages, and the
+ *      GNU ZRTP engine. The GNU ZRTP engine provides methods to
+ *      setup ZRTP message and to analyze received ZRTP messages,
+ *      to compute the crypto data required for SRTP, and to
+ *      maintain the required hashes and HMAC.
+ * </li>
+ * <li>
+ *      The second part of an implementation is specific
+ *      <em>glue</em> code the binds the GNU ZRTP core to the
+ *      actual RTP/SRTP implementation and other operating system
+ *      specific services  such as timers.
+ * </li>
+ * </ul>
+ *
+ * The GNU ZRTP core uses a callback interface class (refer to
+ * ZrtpCallback) to access RTP/SRTP or operating specific methods,
+ * for example to send data via the RTP/SRTP stack, to access
+ * timers, provide mutex handling, and to report events to the
+ * application.
+ *
+ * <b>The ZrtpQueue</b>
+ *
+ * ZrtpQueue implements code that is specific to the GNU ccRTP
+ * implementation. ZrtpQueue also implements the specific code to
+ * provide the mutex and timeout handling to the GNU ZRTP
+ * core. Both, the mutex and the timeout handling, use the GNU
+ * Common C++ library to stay independent of the operating
+ * seystem. For more information refer to the <a
+ * href="http://www.gnutelephony.org/index.php/GNU_Common_C%2B%2B">GNU
+ * Common C++</a> web site.
+ *
+ * To perform its tasks ZrtpQueue
+ * <ul>
+ * <li> extends GNU ccRTP classes to use the underlying
+ *      ccRTP methods and the RTP/SRTP send and receive queues
+ * </li>
+ * <li> implements the ZrtpCallback interface to provide ccRTP
+ *      access and other specific services (timer, mutex) to GNU
+ *      ZRTP
+ * </li>
+ * <li> provides ZRTP specific methods that applications may use
+ *      to control and setup GNU ZRTP
+ * </li>
+ * <li> can register and use an application specific callback
+ *      class (refer to ZrtpUserCallback)
+ * </li>
+ * </ul>
+ *
+ * After instantiating a GNU ZRTP session (see below for a short
+ * example) applications may use the ZRTP specific methods of
+ * ZrtpQueue to control and setup GNU ZRTP, for example enable or
+ * disable ZRTP processing or getting ZRTP status information.
+ *
+ * GNU ZRTP provides a ZrtpUserCallback class that an application
+ * may extend and register with ZrtpQueue. GNU ZRTP and ZrtpQueue
+ * use the ZrtpUserCallback methods to report ZRTP events to the
+ * application. The application may display this information to
+ * the user or act otherwise.
+ *
+ * The following figure depicts the relationships between
+ * ZrtpQueue, ccRTP RTP/SRTP implementation, the GNU ZRTP core,
+ * and an application that provides an ZrtpUserCallback class.
+ *
+@verbatim
+
+                      +----------+
+                      |  ccRTP   |
+                      | RTP/SRTP |
+                      |          |
+                      +----------+
+                           ^
+                           | extends
+                           |
++----------------+      +-----+------+
+|  Application   |      |            |      +-----------------+
+|  instantiates  | uses | ZrtpQueue  | uses |                 |
+| a ZRTP Session +------+ implements +------+    GNU ZRTP     |
+|  and provides  |      |ZrtpCallback|      |      core       |
+|ZrtpUserCallback|      |            |      | implementation  |
++----------------+      +------------+      |  (ZRtp et al)   |
+                                         |                 |
+                                         +-----------------+
+@endverbatim
+ *
+ * Because ZrtpQueue extends the ccRTP RTP/SRTP implementation
+ * (AVPQueue) all public methods defined by ccRTP are also
+ * available for a ZRTP session. ZrtpQueue overwrites some of the
+ * public methods of ccRTP (AVPQueue) to implement ZRTP specific
+ * code.
+ *
+ * GNU ZRTP provides a <em>SymmetricZRTPSession</em> type to
+ * simplify its use. An application uses this type in the same way
+ * as it would use the normal ccRTP <em>SymmetricRTPSession</em>
+ * type. The following short code snippets show how an application
+ * could instantiate ccRTP and GNU ZRTP sessions. The first
+ * snippet shows how to instantiate a ccRTP session:
+ *
+ * @code
+ * ...
+ * #include <ccrtp/rtp.h>
+ * ...
+ *     SymmetricRTPSession tx(pattern.getSsrc(),
+ *                            InetHostAddress("localhost"));
+ * ...
+ *
+ * @endcode
+ *
+ * The same code as above but using a GNU ZRTP session this time:
+ * @code
+ * ...
+ * #include <libzrtpcpp/zrtpccrtp.h>
+ * ...
+ *     SymmetricZRTPSession tx(pattern.getSsrc(),
+ *                             InetHostAddress("localhost"));
+ * ...
+ *
+ * @endcode
+ *
+ * The only differences are the different include statements and
+ * the different session types.
+ *
+ * The <em>demo</em> folder contains a small example that shows
+ * how to use GNU ZRTP.
+ *
+ * Please refer to the GNU ccRTP documentation for a description
+ * of ccRTP methods and functions. This ZrtpQueue documentation
+ * shows the ZRTP specific extensions and describes overloaded
+ * methods and a possible different behaviour.
+ *
+ * @author Werner Dittmann <Werner.Dittmann@t-online.de>
+ */
+
+class __EXPORT ZrtpQueue : public AVPQueue, ZrtpCallback {
+
+public:
+
+    /**
+     * Initialize the ZrtpQueue.
+     *
+     * Before an application can use ZRTP it has to initialize the
+     * ZRTP implementation. This method initializes the timeout
+     * thread and opens a file that contains ZRTP specific
+     * information such as the applications ZID (ZRTP id) and its
+     * retained shared secrets.
+     *
+     * If one application requires several ZRTP sessions all
+     * sessions use the same timeout thread and use the same ZID
+     * file. Therefore an application does not need to do any
+     * synchronisation regading ZID files or timeouts. This is
+     * managed by the ZRTP implementation.
+     *
+     * The current implementation of ZrtpQueue does not support
+     * different ZID files for one application instance. This
+     * restriction may be removed in later versions.
+     *
+     * The application may specify its own ZID file name. If no
+     * ZID file name is specified it defaults to
+     * <code>$HOME/.GNUccRTP.zid</code> if the <code>HOME</code>
+     * environment variable is set. If it is not set the current
+     * directory is used.
+     *
+     * If the method could set up the timeout thread and open the ZID
+     * file then it enables ZRTP processing and returns.
+     *
+     * @param zidFilename
+     *     The name of the ZID file, can be a relative or absolut
+     *     filename.
+     *
+     * @param autoEnable
+     *     if set to true the method automatically sets enableZrtp to
+     *     true. This enables the ZRTP auto-sense mode. Default is true.
+     *
+     * @param config
+     *     this parameter points to ZRTP configuration data. If it is
+     *     NULL then ZrtpQueue uses a default setting. Default is NULL.
+     *
+     * @return
+     *     1 on success, ZRTP processing enabled, -1 on failure,
+     *     ZRTP processing disabled.
+     *
+     */
+    int32_t initialize(const char *zidFilename, bool autoEnable = true,
+                       ZrtpConfigure* config = NULL);
+
+    /*
+     * Applications use the following methods to control ZRTP, for example
+     * to enable ZRTP, set flags etc.
+     */
+
+    /**
+     * Enable or disable ZRTP processing.
+     *
+     * Call this method to enable or disable ZRTP processing after
+     * calling <code>initialize()</code>. This can be done before
+     * using a RTP session or at any time during a RTP session.
+     *
+     * Existing SRTP sessions or currently active ZRTP processing will
+     * not be stopped or disconnected.
+     *
+     * If the application enables ZRTP then:
+     * <ul>
+     * <li>ZrtpQueue starts to send ZRTP Hello packets after at least
+     * one RTP packet was sent and received on the associated RTP
+     * session. Thus if an application enables ZRTP and ZrtpQueue
+     * detects traffic on the RTP session then ZrtpQueue automatically
+     * starts the ZRTP protocol. This automatic start is convenient
+     * for applications that negotiate RTP parameters and set up RTP
+     * sessions but the actual RTP traffic starts some time later.
+     * </li>
+     * <li>ZrtpQueue analyses incoming packets to detect ZRTP
+     * messages. If ZRTP was started, either via automatic start (see
+     * above) or explicitly via startZrtp(), then ZrtpQueue
+     * forwards ZRTP packets to the GNU ZRTP core.
+     * </ul>
+     *
+     * @param onOff
+     *     @c true to enable ZRTP, @c false to disable ZRTP
+     */
+    void setEnableZrtp(bool onOff);
+
+    /**
+     * Return the state of ZRTP enable state.
+     *
+     * @return @c true if ZRTP processing is enabled, @c false
+     * otherwise.
+     */
+    bool isEnableZrtp();
+
+    /**
+     * Set SAS as verified.
+     *
+     * The application may call this method if the user confirmed
+     * (verfied) the Short Authentication String (SAS) with the peer.
+     *
+     * ZRTP calls ZrtpUserCallback#showSAS after it computed the SAS
+     * and the application registered a user callback class. The
+     * application should display the SAS and provide a mechanism at
+     * the user interface that enables the user to confirm the SAS.
+     *
+     * ZRTP remembers the SAS confirmation status together with the
+     * retained secrets data. If both parties confirmed the SAS then
+     * ZRTP informs the application about this status on the next ZRTP
+     * session.
+     *
+     * For more detailed information regarding SAS please refer to the
+     * ZRTP specification, chapter 8.
+     */
+    void SASVerified();
+
+    /**
+     * Reset the SAS verfied flag for the current user's retained secrets.
+     *
+     */
+    void resetSASVerified();
+
+    /**
+     * To confirm a go clear request.
+     *
+     * Call this method if the user confirmed a go clear (secure mode off).
+     */
+    void goClearOk();
+
+    /**
+     * Request to switch off secure mode.
+     *
+     * Call this method is the user itself wants to switch off secure
+     * mode (go clear). After sending the "go clear" request to the peer
+     * ZRTP immediatly switch off SRTP processing. Every RTP data is sent
+     * in clear after the go clear request.
+     */
+    void requestGoClear();
+
+    /**
+     * Set the auxilliary secret.
+     *
+     * Use this method to set the srtps secret data. Refer to ZRTP
+     * specification, chapter 5.3 ff
+     *
+     * @param data
+     *     Points to the auxilliary secret data.
+     * @param length
+     *     Length of the auxilliary secrect in bytes
+     */
+    void setAuxSecret(uint8_t* data, int32_t length);
+
+    /**
+     * Set the application's callback class.
+     *
+     * The destructor of ZrtpQueue also destorys the user callback
+     * class if it was set. The application must not delete the
+     * callback object or use/reference the callback object after
+     * ZrtpQueue was destroyed.
+     *
+     * @param ucb
+     *     Implementation of the application's ZrtpUserCallback class
+     */
+    void setUserCallback(ZrtpUserCallback* ucb);
+
+    /**
+     * Set the client ID for ZRTP Hello message.
+     *
+     * The GNU ccRTP client may set its id to identify itself in the
+     * ZRTP Hello message. The maximum length is 16 characters. A
+     * shorter id string is possible, it will be filled with blanks. A
+     * longer id string will be truncated to 16 characters. The
+     * standard client id is <code>'GNU ccRTP ZRTP '</code> (without
+     * the quotes).
+     *
+     * Setting the client's id must be done before calling
+     * ZrtpQueue#initialize() or ZrtpQueue#startZrtp() .
+     *
+     * @param id
+     *     The client's id string
+     */
+    void setClientId(std::string id);
+
+    /**
+     * Get the ZRTP Hello Hash data.
+     *
+     * Use this method to get the ZRTP Hello Hash data. The method
+     * returns the data as a string containing hex-digits. Refer
+     * to ZRTP specification, chapter 9.1.
+     *
+     * @return
+     *    a std:string containing the Hello hash value as hex-digits. The
+     *    hello hash is available immediatly after calling
+     *    ZrtpQueue#startZrtp. If ZRTP was not started the method returns
+     *    an empty string.
+     */
+    std::string getHelloHash();
+
+    /**
+     * Get the peer's ZRTP Hello Hash data.
+     *
+     * Use this method to get the peer's ZRTP Hello Hash data. The method
+     * returns the data as a string containing the ZRTP protocol version and
+     * hex-digits.
+     *
+     * The peer's hello hash is available only after ZRTP received a hello. If
+     * no data is available the function returns an empty string.
+     *
+     * Refer to ZRTP specification, chapter 8.
+     *
+     * @return
+     *    a std:string containing the Hello version and the hello hash as hex digits.
+     */
+    std::string getPeerHelloHash();
+
+    /**
+     * Get Multi-stream parameters.
+     *
+     * Use this method to get the Multi-stream that were computed during
+     * the ZRTP handshake. An application may use these parameters to
+     * enable multi-stream processing for an associated SRTP session.
+     *
+     * Refer to chapter 5.4.2 in the ZRTP specification for further details
+     * and restriction how and when to use multi-stream mode.
+     *
+     * @return
+     *    a string that contains the multi-stream parameters. The application
+     *    must not modify the contents of this string, it is opaque data. The
+     *    application may hand over this string to a new ZrtpQueue instance
+     *    to enable multi-stream processing for this ZrtpQueue. If ZRTP was
+     *    not started or ZRTP is not yet in secure state the method returns an
+     *    empty string.
+     *
+     * @see setMultiStrParams()
+     */
+    std::string getMultiStrParams();
+
+    /**
+     * Set Multi-stream parameters.
+     *
+     * Use this method to set the parameters required to enable Multi-stream
+     * processing of ZRTP. The multi-stream parameters must be set before the
+     * application starts the ZRTP protocol engine.
+     *
+     * Refer to chapter 5.4.2 in the ZRTP specification for further details
+     * of multi-stream mode.
+     *
+     * @param parameters
+     *     A string that contains the multi-stream parameters that this
+     *     new ZrtpQueue instanace shall use.
+     *
+     * @see getMultiStrParams()
+     */
+    void setMultiStrParams(std::string parameters);
+
+    /**
+     * Check if this ZRTP use Multi-stream.
+     *
+     * Use this method to check if this ZRTP instance uses multi-stream. Even
+     * if the application provided multi-stram parameters it may happen that
+     * full DH mode was used. Refer to chapters 5.2 and 5.4.2 in the ZRTP #
+     * when this may happen.
+     *
+     * @return
+     *     True if multi-stream is used, false otherwise.
+     */
+    bool isMultiStream();
+
+    /**
+     * Check if the other ZRTP client supports Multi-stream.
+     *
+     * Use this method to check if the other ZRTP client supports
+     * Multi-stream mode.
+     *
+     * @return
+     *     True if multi-stream is available, false otherwise.
+     */
+    bool isMultiStreamAvailable();
+
+    /**
+     * Accept a PBX enrollment request.
+     *
+     * If a PBX service asks to enroll the MiTM key and the user accepts this
+     * requtes, for example by pressing an OK button, the client application
+     * shall call this method and set the parameter <code>accepted</code> to
+     * true. If the user does not accept the request set the parameter to
+     * false.
+     *
+     * @param accepted
+     *     True if the enrollment request is accepted, false otherwise.
+     */
+    void acceptEnrollment(bool accepted);
+
+    /**
+     * Get the commited SAS rendering algorithm for this ZRTP session.
+     *
+     * @return the commited SAS rendering algorithm
+     */
+    std::string getSasType();
+
+    /**
+     * Get the computed SAS hash for this ZRTP session.
+     *
+     * A PBX ZRTP back-to-Back function uses this function to get the SAS
+     * hash of an enrolled client to construct the SAS relay packet for
+     * the other client.
+     *
+     * @return a refernce to the byte array that contains the full
+     *         SAS hash.
+     */
+    uint8_t* getSasHash();
+
+    /**
+     * Send the SAS relay packet.
+     *
+     * The method creates and sends a SAS relay packet according to the ZRTP
+     * specifications. Usually only a MitM capable user agent (PBX) uses this
+     * function.
+     *
+     * @param sh the full SAS hash value
+     * @param render the SAS rendering algorithm
+     */
+    bool sendSASRelayPacket(uint8_t* sh, std::string render);
+
+    /**
+     * Check the state of the MitM mode flag.
+     *
+     * If true then this ZRTP session acts as MitM, usually enabled by a PBX
+     * client (user agent)
+     *
+     * @return state of mitmMode
+     */
+    bool isMitmMode();
+
+    /**
+     * Set the state of the MitM mode flag.
+     *
+     * If MitM mode is set to true this ZRTP session acts as MitM, usually
+     * enabled by a PBX client (user agent).
+     *
+     * @param mitmMode defines the new state of the mitmMode flag
+     */
+    void setMitmMode(bool mitmMode);
+
+    /**
+     * Enable or disable paranoid mode.
+     *
+     * The Paranoid mode controls the behaviour and handling of the SAS verify flag. If
+     * Panaoid mode is set to flase then ZRtp applies the normal handling. If Paranoid
+     * mode is set to true then the handling is:
+     *
+     * <ul>
+     * <li> always set the SAS verify flag to <code>false</code> at srtpSecretsOn() callback. The
+     *      user interface (UI) must show <b>SAS not verified</b>. See implementation note below.</li>
+     * <li> don't set the SAS verify flag in the <code>Confirm</code> packets, thus forcing the other
+     *      peer to report <b>SAS not verified</b>.</li>
+     * <li> ignore the <code>SASVerified()</code> function, thus do not set the SAS verified flag
+     *      in the ZRTP cache. </li>
+     * <li> Disable the <em>Trusted PBX MitM</em> feature. Just send the <code>SASRelay</code> packet
+     *      but do not process the relayed data. This protects the user from a malicious
+     *      "trusted PBX".</li>
+     * </ul>
+     * ZRtp performs alls other steps during the ZRTP negotiations as usual, in particular it
+     * computes, compares, uses, and stores the retained secrets. This avoids unnecessary warning
+     * messages. The user may enable or disable the Paranoid mode on a call-by-call basis without
+     * breaking the key continuity data.
+     *
+     * <b>Implementation note:</b><br/>
+     * An application shall <b>always display the SAS if the SAS verify flag is <code>false</code></b>.
+     * The application shall remind the user to compare the SAS code, for example using larger fonts,
+     * different colours and other display features.
+     */
+    void setParanoidMode(bool yesNo);
+
+    /**
+     * Check status of paranoid mode.
+     *
+     * @return
+     *    Returns true if paranoid mode is enabled.
+     */
+    bool isParanoidMode();
+
+    /**
+     * Check the state of the enrollment mode.
+     *
+     * If true then we will set the enrollment flag (E) in the confirm
+     * packets and performs the enrollment actions. A MitM (PBX) enrollment service sets this flagstarted this ZRTP
+     * session. Can be set to true only if mitmMode is also true.
+     * @return status of the enrollmentMode flag.
+     */
+    bool isEnrollmentMode();
+
+    /**
+     * Check the state of the enrollment mode.
+     *
+     * If true then we will set the enrollment flag (E) in the confirm
+     * packets and perform the enrollment actions. A MitM (PBX) enrollment
+     * service must sets this mode to true.
+     *
+     * Can be set to true only if mitmMode is also true.
+     *
+     * @param enrollmentMode defines the new state of the enrollmentMode flag
+     */
+    void setEnrollmentMode(bool enrollmentMode);
+
+    /**
+     * Check if a peer's cache entry has a vaild MitM key.
+     *
+     * If true then the other peer ha a valid MtiM key, i.e. the peer has performed
+     * the enrollment procedure. A PBX ZRTP Back-2-Back application can use this function
+     * to check which of the peers is enrolled.
+     *
+     * @return True if the other peer has a valid Mitm key (is enrolled).
+     */
+    bool isPeerEnrolled();
+
+    /**
+     * Set the state of the SAS signature mode flag.
+     *
+     * If SAS signature mode is set to true this ZRTP session support SAS signature
+     * callbacks and signature transfer between clients.
+     *
+     * @param sasSignMode defines the new state of the sasSignMode flag
+     */
+    void setSignSas(bool sasSignMode);
+
+    /**
+     * Set signature data
+     *
+     * This functions stores signature data and transmitts it during ZRTP
+     * processing to the other party as part of the Confirm packets. Refer to
+     * chapters 6.7 and 8.2 in the ZRTP specification.
+     *
+     * @param data
+     *    The signature data including the signature type block. The method
+     *    copies this data into the Confirm packet at signature type block.
+     * @param length
+     *    The length of the signature data in bytes. This length must be
+     *    multiple of 4.
+     * @return
+     *    True if the method stored the data, false otherwise.
+     */
+    bool setSignatureData(uint8* data, int32 length);
+
+    /**
+     * Get signature data
+     *
+     * This functions returns signature data that was receivied during ZRTP
+     * processing. Refer to chapters 6.7 and 8.2.
+     *
+     * @return
+     *    Pointer to signature data. This is a pointer to volatile data that is
+     *    only valid during the checkSASSignature() callback. The application
+     *    shall copy the data if necessary.
+     */
+    const uint8* getSignatureData();
+
+    /**
+     * Get length of signature data
+     *
+     * This functions returns the length of signature data that was receivied
+     * during ZRTP processing. Refer to chapters 6.7 and 8.2.
+     *
+     * @return
+     *    Length in bytes of the received signature data. The method returns
+     *    zero if no signature data avilable.
+     */
+    int32 getSignatureLength();
+
+    /**
+     * Put data into the RTP output queue.
+     *
+     * This is used to create a data packet in the send queue.
+     * Sometimes a "NULL" or empty packet will be used instead, and
+     * these are known as "silent" packets.  "Silent" packets are
+     * used simply to "push" the scheduler along more accurately
+     * by giving the appearence that a next packet is waiting to
+     * be sent and to provide a valid timestamp for that packet.
+     *
+     * This method overrides the same method in OutgoingDataQueue class.
+     * During ZRTP processing it may be necessary to control the
+     * flow of outgoing RTP payload packets (GoClear processing).
+     *
+     * @param stamp Timestamp for expected send time of packet.
+     * @param data Value or NULL if special "silent" packet.
+     * @param len May be 0 to indicate a default by payload type.
+     **/
+    void
+    putData(uint32 stamp, const unsigned char* data = NULL, size_t len = 0);
+
+    /**
+     * Immediatly send a data packet.
+     *
+     * This is used to create a data packet and send it immediately.
+     * Sometimes a "NULL" or empty packet will be used instead, and
+     * these are known as "silent" packets.  "Silent" packets are
+     * used simply to "push" the scheduler along more accurately
+     * by giving the appearence that a next packet is waiting to
+     * be sent and to provide a valid timestamp for that packet.
+     *
+     * This method overrides the same method in OutgoingDataQueue
+     * class.  During ZRTP processing it may be necessary to
+     * control the flow of outgoing RTP payload packets (GoClear
+     * processing).
+     *
+     * @param stamp Timestamp immediate send time of packet.
+     * @param data Value or NULL if special "silent" packet.
+     * @param len May be 0 to indicate a default by payload type.
+     **/
+    void
+    sendImmediate(uint32 stamp, const unsigned char* data = NULL, size_t len = 0);
+
+    /**
+     * Starts the ZRTP protocol engine.
+     *
+     * Applications may call this method to immediatly start the ZRTP protocol
+     * engine any time after initializing ZRTP and setting optinal parameters,
+     * for example client id or multi-stream parameters.
+     *
+     * If the application does not call this method but sucessfully initialized
+     * the ZRTP engine using <code>initialize()</code> then ZRTP also starts
+     * after the application sent and received RTP packets. An application can
+     * disable this automatic, delayed start of the ZRTP engine using
+     * <code>setEnableZrtp(false)</code> before sending or receiving RTP
+     * packets.
+     *
+     */
+    void startZrtp();
+
+    /**
+     * Stops the ZRTP protocol engine.
+     *
+     * Applications call this method to stop the ZRTP protocol
+     * engine.
+     *
+     */
+    void stopZrtp();
+
+    /**
+     * Get other party's ZID (ZRTP Identifier) data
+     *
+     * This functions returns the other party's ZID that was receivied
+     * during ZRTP processing.
+     *
+     * The ZID data can be retrieved after ZRTP receive the first Hello
+     * packet from the other party. The application may call this method
+     * for example during SAS processing in showSAS(...) user callback
+     * method.
+     *
+     * @param data
+     *    Pointer to a data buffer. This buffer must have a size of
+     *    at least 12 bytes (96 bit) (ZRTP Identifier, see chap. 4.9)
+     * @return
+     *    Number of bytes copied into the data buffer - must be equivalent
+     *    to 96 bit, usually 12 bytes.
+     */
+    int32 getPeerZid(uint8* data);
+
+protected:
+    friend class TimeoutProvider<std::string, ost::ZrtpQueue*>;
+
+    /**
+     * A hook that gets called if the decoding of an incoming SRTP
+     * was erroneous
+     *
+     * @param pkt
+     *     The SRTP packet with error.
+     * @param errorCode
+     *     The error code: -1 - SRTP authentication failure, -2 - replay
+     *     check failed
+     * @return
+     *     True: put the packet in incoming queue for further processing
+     *     by the applications; false: dismiss packet. The default
+     *     implementation returns false.
+     */
+    virtual bool
+    onSRTPPacketError(IncomingRTPPkt& pkt, int32 errorCode);
+
+    /**
+     * Handle timeout event forwarded by the TimeoutProvider.
+     *
+     * Just call the ZRTP engine for further processing.
+     */
+    void handleTimeout(const std::string &c);
+
+    /**
+     * This function is used by the service thread to process
+     * the next incoming packet and place it in the receive list.
+     *
+     * This class overloads the function of IncomingDataQueue
+     * implementation.
+     *
+     * @return number of payload bytes received,  <0 if error.
+     */
+    virtual size_t takeInDataPacket();
+
+    /*
+     * The following methods implement the GNU ZRTP callback interface.
+     * For detailed documentation refer to file ZrtpCallback.h
+     */
+    int32_t sendDataZRTP(const unsigned char* data, int32_t length);
+
+    int32_t activateTimer(int32_t time);
+
+    int32_t cancelTimer();
+
+    void sendInfo(GnuZrtpCodes::MessageSeverity severity, int32_t subCode);
+
+    bool srtpSecretsReady(SrtpSecret_t* secrets, EnableSecurity part);
+
+    void srtpSecretsOff(EnableSecurity part);
+
+    void srtpSecretsOn(std::string c, std::string s, bool verified);
+
+    void handleGoClear();
+
+    void zrtpNegotiationFailed(GnuZrtpCodes::MessageSeverity severity, int32_t subCode);
+
+    void zrtpNotSuppOther();
+
+    void synchEnter();
+
+    void synchLeave();
+
+    void zrtpAskEnrollment(GnuZrtpCodes::InfoEnrollment info);
+
+    void zrtpInformEnrollment(GnuZrtpCodes::InfoEnrollment  info);
+
+    void signSAS(uint8_t* sasHash);
+
+    bool checkSASSignature(uint8_t* sasHash);
+
+    /*
+     * End of ZrtpCallback functions.
+     */
+
+    ZrtpQueue(uint32 size = RTPDataQueue::defaultMembersHashSize,
+              RTPApplication& app = defaultApplication());
+
+    /**
+     * Local SSRC is given instead of computed by the queue.
+     */
+    ZrtpQueue(uint32 ssrc, uint32 size =
+                  RTPDataQueue::defaultMembersHashSize,
+              RTPApplication& app = defaultApplication());
+
+    virtual ~ZrtpQueue();
+
+private:
+    void init();
+    size_t rtpDataPacket(unsigned char* packet, int32 rtn,
+                         InetHostAddress network_address,
+                         tpport_t transport_port);
+
+    ZRtp *zrtpEngine;
+    ZrtpUserCallback* zrtpUserCallback;
+
+    std::string clientIdString;
+
+    bool enableZrtp;
+
+    int32 secureParts;
+
+    int16 senderZrtpSeqNo;
+    ost::Mutex synchLock;   // Mutex for ZRTP (used by ZrtpStateClass)
+    uint32 peerSSRC;
+    bool started;
+    bool mitmMode;
+    bool signSas;
+    bool enableParanoidMode;
+};
+
+class IncomingZRTPPkt : public IncomingRTPPkt {
+
+public:
+    /**
+     * Build a ZRTP packet object from a data buffer.
+     *
+     * @param block pointer to the buffer the whole packet is stored in.
+     * @param len length of the whole packet, expressed in octets.
+     *
+     **/
+
+    IncomingZRTPPkt(const unsigned char* block, size_t len);
+
+    ~IncomingZRTPPkt()
+    { }
+
+    uint32
+    getZrtpMagic() const;
+
+    uint32
+    getSSRC() const;
+};
+
+class OutgoingZRTPPkt : public OutgoingRTPPkt {
+
+public:
+    /**
+     * Construct a new ZRTP packet to be sent.
+     *
+     * A new copy in memory (holding all this components
+     * along with the fixed header) is created.
+     *
+     * @param hdrext whole header extension.
+     * @param hdrextlen size of whole header extension, in octets.
+     **/
+    OutgoingZRTPPkt(const unsigned char* const hdrext, uint32 hdrextlen);
+    ~OutgoingZRTPPkt()
+    { }
+};
+
+END_NAMESPACE
+
+#endif
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
+
