* #35924 (zrtp): switch to libzrtpcpp
diff --git a/jni/libzrtp/sources/clients/tivi/CtZrtpSession.cpp b/jni/libzrtp/sources/clients/tivi/CtZrtpSession.cpp
new file mode 100644
index 0000000..8588744
--- /dev/null
+++ b/jni/libzrtp/sources/clients/tivi/CtZrtpSession.cpp
@@ -0,0 +1,652 @@
+/*
+ * Tivi client glue code for ZRTP.
+ * Copyright (c) 2012 Slient Circle LLC.  All rights reserved.
+ *
+ *
+ * @author Werner Dittmann <Werner.Dittmann@t-online.de>
+ */
+
+#include <string>
+#include <stdio.h>
+
+#include <libzrtpcpp/ZIDCache.h>
+#include <libzrtpcpp/ZRtp.h>
+
+#include <CtZrtpStream.h>
+#include <CtZrtpCallback.h>
+#include <CtZrtpSession.h>
+
+#include <common/Thread.h>
+
+static CMutexClass sessionLock;
+
+const char *getZrtpBuildInfo()
+{
+    return zrtpBuildInfo;
+}
+CtZrtpSession::CtZrtpSession() : mitmMode(false), signSas(false), enableParanoidMode(false), isReady(false),
+    zrtpEnabled(true), sdesEnabled(true) {
+
+    clientIdString = clientId;
+    streams[AudioStream] = NULL;
+    streams[VideoStream] = NULL;
+}
+
+int CtZrtpSession::initCache(const char *zidFilename) {
+    ZIDCache* zf = getZidCacheInstance();
+    if (!zf->isOpen()) {
+        std::string fname;
+        if (zidFilename == NULL) {
+            char *home = getenv("HOME");
+            std::string baseDir = (home != NULL) ? (std::string(home) + std::string("/."))
+                                                    : std::string(".");
+            fname = baseDir + std::string("GNUZRTP.zid");
+            zidFilename = fname.c_str();
+        }
+        if (zf->open((char *)zidFilename) < 0) {
+            return -1;
+        }
+    }
+    return 1;
+}
+
+int CtZrtpSession::init(bool audio, bool video, ZrtpConfigure* config)
+{
+    int32_t ret = 1;
+
+    synchEnter();
+
+    ZrtpConfigure* configOwn = NULL;
+    if (config == NULL) {
+        config = configOwn = new ZrtpConfigure();
+        setupConfiguration(config);
+        config->setTrustedMitM(true);
+    }
+    config->setParanoidMode(enableParanoidMode);
+
+    ZIDCache* zf = getZidCacheInstance();
+    if (!zf->isOpen()) {
+        ret = -1;
+    }
+    if (ret > 0) {
+        const uint8_t* ownZid = zf->getZid();
+        CtZrtpStream *stream;
+
+        // Create CTZrtpStream object only once, they are availbe for the whole
+        // lifetime of the session.
+        if (audio) {
+            if (streams[AudioStream] == NULL)
+                streams[AudioStream] = new CtZrtpStream();
+            stream = streams[AudioStream];
+            stream->zrtpEngine = new ZRtp((uint8_t*)ownZid, stream, clientIdString, config, mitmMode, signSas);
+            stream->type = Master;
+            stream->index = AudioStream;
+            stream->session = this;
+        }
+        if (video) {
+            if (streams[VideoStream] == NULL)
+                streams[VideoStream] = new CtZrtpStream();
+            stream = streams[VideoStream];
+            stream->zrtpEngine = new ZRtp((uint8_t*)ownZid, stream, clientIdString, config);
+            stream->type = Slave;
+            stream->index = VideoStream;
+            stream->session = this;
+        }
+    }
+    if (configOwn != NULL) {
+        delete configOwn;
+    }
+    synchLeave();
+    isReady = true;
+    return ret;
+}
+
+CtZrtpSession::~CtZrtpSession() {
+
+    delete streams[AudioStream];
+    delete streams[VideoStream];
+}
+
+void zrtp_log(const char *tag, const char *buf);
+void CtZrtpSession::setupConfiguration(ZrtpConfigure *conf) {
+
+// Set _WITHOUT_TIVI_ENV to a real name that is TRUE if the Tivi client is compiled/built.
+#ifdef _WITHOUT_TIVI_ENV
+#define GET_CFG_I(RET,_KEY)
+#else
+void *findGlobalCfgKey(char *key, int iKeyLen, int &iSize, char **opt, int *type);
+#define GET_CFG_I(RET,_KEY) {int *p=(int*)findGlobalCfgKey((char*)_KEY,sizeof(_KEY)-1,iSZ,&opt,&type);if(p && iSZ==4)RET=*p;else RET=-1;}
+#endif
+
+
+// The next three vars are used in case of a real Tivi compile, see macro above.
+    int iSZ;
+    char *opt;
+    int type;
+    void zrtp_log( const char *tag, const char *buf);
+
+    int b32sas = 0, iDisableDH2K = 0, iDisableAES256 = 0, iPreferDH2K = 0;
+    int iDisableECDH256 = 0, iDisableECDH384 = 0, iEnableSHA384 = 1;
+    int iDisableSkein = 0, iDisableTwofish = 0, iPreferNIST = 0;
+    int iDisableSkeinHash = 0, iDisableBernsteinCurve25519 = 0, iDisableBernsteinCurve3617 = 0;
+
+    GET_CFG_I(b32sas, "iDisable256SAS");
+    GET_CFG_I(iDisableAES256, "iDisableAES256");
+    GET_CFG_I(iDisableDH2K, "iDisableDH2K");
+    GET_CFG_I(iPreferDH2K, "iPreferDH2K");
+
+    GET_CFG_I(iDisableECDH256, "iDisableECDH256");
+    GET_CFG_I(iDisableECDH384, "iDisableECDH384");
+    GET_CFG_I(iEnableSHA384, "iEnableSHA384");
+    GET_CFG_I(iDisableSkein, "iDisableSkein");
+    GET_CFG_I(iDisableTwofish, "iDisableTwofish");
+    GET_CFG_I(iPreferNIST, "iPreferNIST");
+
+    GET_CFG_I(iDisableSkeinHash, "iDisableSkeinHash");
+    GET_CFG_I(iDisableBernsteinCurve25519, "iDisableBernsteinCurve25519");
+    GET_CFG_I(iDisableBernsteinCurve3617, "iDisableBernsteinCurve3617");
+
+    conf->clear();
+
+    /*
+     * Setting the selection policy is a more generic policy than the iPreferNIST
+     * configuration set by the user. The selection policy is a decision of the
+     * client, not the user
+     */
+    conf->setSelectionPolicy(ZrtpConfigure::PreferNonNist);
+
+    /*
+     * Handling of iPreferNIST: if this is false (== 0) then we add the non-NIST algorithms
+     * to the configuration and place them in front of the NIST algorithms. Refer to RFC6189
+     * section 4.1.2 regarding selection of the public key algorithm.
+     * 
+     * With the configuration flags we can enable/disable each ECC PK algorithm separately.
+     * 
+     */
+    if (iPreferNIST == 0) {
+        if (iDisableBernsteinCurve3617 == 0)
+            conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E414"));
+        if (iDisableECDH384 == 0)
+            conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC38"));
+    }
+    else {
+        if (iDisableECDH384 == 0)
+            conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC38"));
+        if (iDisableBernsteinCurve3617 == 0)
+            conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E414"));
+    }
+
+    if (iPreferNIST == 0) {
+        if (iDisableBernsteinCurve25519 == 0)
+            conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E255"));
+        if (iDisableECDH256 == 0)
+            conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC25"));
+    }
+    else {
+        if (iDisableECDH256 == 0)
+            conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC25"));
+        if (iDisableBernsteinCurve25519 == 0)
+            conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E255"));
+    }
+
+    // DH2K handling: if DH2K not disabled and prefered put it infrom of DH3K,
+    // If not preferred and not disabled put if after DH3K. Don't use DH2K if
+    // it's not enabled at all (iDisableDH2K == 1)
+    if (iPreferDH2K && iDisableDH2K == 0) {
+        conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH2k"));
+    }
+    conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH3k"));
+    if (iPreferDH2K == 0 && iDisableDH2K == 0)
+        conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH2k"));
+
+    conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("Mult"));
+
+
+    // Handling of Hash algorithms: similar to PK, if PreferNIST is false
+    // then put Skein in fromt oF SHA. Regardless if the Hash is enabled or
+    // not: if configuration enables a large curve then also use the large
+    // hashes.
+    if (iPreferNIST == 0) {
+        if (iDisableSkeinHash == 0 || iDisableBernsteinCurve3617 == 0)
+            conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN3"));
+        if (iEnableSHA384 == 1 || iDisableECDH384 == 0) 
+            conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("S384"));
+    }
+    else {
+        if (iEnableSHA384 == 1 || iDisableECDH384 == 0) 
+            conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("S384"));
+        if (iDisableSkeinHash == 0 || iDisableBernsteinCurve3617 == 0)
+            conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN3"));
+    }
+
+    if (iPreferNIST == 0) {
+        if (iDisableSkeinHash == 0)
+            conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN2"));
+        conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("S256"));
+    }
+    else {
+        conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("S256"));
+        if (iDisableSkeinHash == 0)
+            conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN2"));
+    }
+
+    // Handling of Symmetric algorithms: always prefer twofish (regardless
+    // of NIST setting) if it is not disabled. iDisableAES256 means: disable
+    // large ciphers
+    if (iDisableAES256 == 0) {
+        if (iDisableTwofish == 0)
+            conf->addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("2FS3"));
+        conf->addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("AES3"));
+    }
+
+    if (iDisableTwofish == 0)
+        conf->addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("2FS1"));
+    conf->addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("AES1"));
+
+    if (b32sas == 1) {
+        conf->addAlgo(SasType, zrtpSasTypes.getByName("B32 "));
+    }
+    else {
+        conf->addAlgo(SasType, zrtpSasTypes.getByName("B256"));
+        conf->addAlgo(SasType, zrtpSasTypes.getByName("B32 "));
+    }
+
+    if (iPreferNIST == 0) {
+        if (iDisableSkein == 0) {
+            conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("SK32"));
+            conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("SK64"));
+        }
+        conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("HS32"));
+        conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("HS80"));
+    }
+    else {
+        conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("HS32"));
+        conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("HS80"));
+        if (iDisableSkein == 0) {
+            conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("SK32"));
+            conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("SK64"));
+        }
+    }
+}
+
+void CtZrtpSession::setUserCallback(CtZrtpCb* ucb, streamName streamNm) {
+    if (!(streamNm >= 0 && streamNm <= AllStreams && streams[streamNm] != NULL))
+        return;
+
+    if (streamNm == AllStreams) {
+        for (int sn = 0; sn < AllStreams; sn++)
+            streams[sn]->setUserCallback(ucb);
+    }
+    else
+        streams[streamNm]->setUserCallback(ucb);
+}
+
+void CtZrtpSession::setSendCallback(CtZrtpSendCb* scb, streamName streamNm) {
+    if (!(streamNm >= 0 && streamNm <= AllStreams && streams[streamNm] != NULL))
+        return;
+
+    if (streamNm == AllStreams) {
+        for (int sn = 0; sn < AllStreams; sn++)
+            streams[sn]->setSendCallback(scb);
+    }
+    else
+        streams[streamNm]->setSendCallback(scb);
+
+}
+
+void CtZrtpSession::masterStreamSecure(CtZrtpStream *masterStream) {
+    // Here we know that the AudioStream is the master and VideoStream the slave.
+    // Otherwise we need to loop and find the Master stream and the Slave streams.
+
+    multiStreamParameter = masterStream->zrtpEngine->getMultiStrParams();
+    CtZrtpStream *strm = streams[VideoStream];
+    if (strm->enableZrtp) {
+        strm->zrtpEngine->setMultiStrParams(multiStreamParameter);
+        strm->zrtpEngine->startZrtpEngine();
+        strm->started = true;
+        strm->tiviState = eLookingPeer;
+        if (strm->zrtpUserCallback != 0)
+            strm->zrtpUserCallback->onNewZrtpStatus(this, NULL, strm->index);
+
+    }
+}
+
+int CtZrtpSession::startIfNotStarted(unsigned int uiSSRC, int streamNm) {
+    if (!(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return 0;
+
+    if ((streamNm == VideoStream && !isSecure(AudioStream)) || streams[streamNm]->started)
+        return 0;
+
+    start(uiSSRC, streamNm == VideoStream ? CtZrtpSession::VideoStream : CtZrtpSession::AudioStream);
+    return 0;
+}
+
+void CtZrtpSession::start(unsigned int uiSSRC, CtZrtpSession::streamName streamNm) {
+    if (!zrtpEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return;
+
+    CtZrtpStream *stream = streams[streamNm];
+
+    stream->ownSSRC = uiSSRC;
+    stream->enableZrtp = true;
+    if (stream->type == Master) {
+        stream->zrtpEngine->startZrtpEngine();
+        stream->started = true;
+        stream->tiviState = eLookingPeer;
+        if (stream->zrtpUserCallback != 0)
+            stream->zrtpUserCallback->onNewZrtpStatus(this, NULL, stream->index);
+        return;
+    }
+    // Process a Slave stream.
+    if (!multiStreamParameter.empty()) {        // Multi-stream parameters available
+        stream->zrtpEngine->setMultiStrParams(multiStreamParameter);
+        stream->zrtpEngine->startZrtpEngine();
+        stream->started = true;
+        stream->tiviState = eLookingPeer;
+        if (stream->zrtpUserCallback != 0)
+            stream->zrtpUserCallback->onNewZrtpStatus(this, NULL, stream->index);
+    }
+}
+
+void CtZrtpSession::stop(streamName streamNm) {
+    if (!(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return;
+
+    streams[streamNm]->isStopped = true;
+}
+
+void CtZrtpSession::release() {
+    release(AudioStream);
+    release(VideoStream);
+}
+
+void CtZrtpSession::release(streamName streamNm) {
+    if (!(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return;
+
+    CtZrtpStream *stream = streams[streamNm];
+    stream->stopStream();                      // stop and reset stream
+}
+
+void CtZrtpSession::setLastPeerNameVerify(const char *name, int iIsMitm) {
+    CtZrtpStream *stream = streams[AudioStream];
+
+    if (!isReady || !stream || stream->isStopped)
+        return;
+
+    uint8_t peerZid[IDENTIFIER_LEN];
+    std::string nm(name);
+    stream->zrtpEngine->getPeerZid(peerZid);
+    getZidCacheInstance()->putPeerName(peerZid, nm);
+    setVerify(1);
+}
+
+int CtZrtpSession::isSecure(streamName streamNm) {
+    if (!(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return 0;
+
+    CtZrtpStream *stream = streams[streamNm];
+    return stream->isSecure();
+}
+
+bool CtZrtpSession::processOutoingRtp(uint8_t *buffer, size_t length, size_t *newLength, streamName streamNm) {
+    if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return false;
+
+    CtZrtpStream *stream = streams[streamNm];
+    if (stream->isStopped)
+        return false;
+
+    return stream->processOutgoingRtp(buffer, length, newLength);
+}
+
+int32_t CtZrtpSession::processIncomingRtp(uint8_t *buffer, size_t length, size_t *newLength, streamName streamNm) {
+    if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return fail;
+
+    CtZrtpStream *stream = streams[streamNm];
+    if (stream->isStopped)
+        return fail;
+
+    return stream->processIncomingRtp(buffer, length, newLength);
+}
+
+bool CtZrtpSession::isStarted(streamName streamNm) {
+    if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return false;
+
+    return streams[streamNm]->isStarted();
+}
+
+bool CtZrtpSession::isEnabled(streamName streamNm) {
+    if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return false;
+
+    CtZrtpStream *stream = streams[streamNm];
+    if (stream->isStopped)
+        return false;
+
+    return stream->isEnabled();
+}
+
+CtZrtpSession::tiviStatus CtZrtpSession::getCurrentState(streamName streamNm) {
+    if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return eWrongStream;
+
+    CtZrtpStream *stream = streams[streamNm];
+    if (stream->isStopped)
+        return eWrongStream;
+
+    return stream->getCurrentState();
+}
+
+CtZrtpSession::tiviStatus CtZrtpSession::getPreviousState(streamName streamNm) {
+    if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return eWrongStream;
+
+    CtZrtpStream *stream = streams[streamNm];
+    if (stream->isStopped)
+        return eWrongStream;
+
+    return stream->getPreviousState();
+}
+
+bool CtZrtpSession::isZrtpEnabled() {
+    return zrtpEnabled;
+}
+
+bool CtZrtpSession::isSdesEnabled() {
+    return sdesEnabled;
+}
+
+void CtZrtpSession::setZrtpEnabled(bool yesNo) {
+    zrtpEnabled = yesNo;
+}
+
+void CtZrtpSession::setSdesEnabled(bool yesNo) {
+    sdesEnabled = yesNo;
+}
+
+int CtZrtpSession::getSignalingHelloHash(char *helloHash, streamName streamNm, int32_t index) {
+    if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return 0;
+
+    CtZrtpStream *stream = streams[streamNm];
+    if (stream->isStopped)
+        return 0;
+
+    return stream->getSignalingHelloHash(helloHash, index);
+}
+
+void CtZrtpSession::setSignalingHelloHash(const char *helloHash, streamName streamNm) {
+    if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return;
+
+    CtZrtpStream *stream = streams[streamNm];
+    if (stream->isStopped)
+        return;
+
+    stream->setSignalingHelloHash(helloHash);
+}
+
+void CtZrtpSession::setVerify(int iVerified) {
+    CtZrtpStream *stream = streams[AudioStream];
+
+    if (!isReady || !stream || stream->isStopped)
+        return;
+
+    if (iVerified) {
+        stream->zrtpEngine->SASVerified();
+        stream->sasVerified = true;
+    }
+    else {
+        stream->zrtpEngine->resetSASVerified();
+        stream->sasVerified = false;
+    }
+}
+
+int CtZrtpSession::getInfo(const char *key, uint8_t *buffer, size_t maxLen, streamName streamNm) {
+    if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return fail;
+
+    CtZrtpStream *stream = streams[streamNm];
+    return stream->getInfo(key, (char*)buffer, (int)maxLen);
+}
+
+int CtZrtpSession::enrollAccepted(char *p) {
+    if (!isReady || !(streams[AudioStream] != NULL))
+        return fail;
+
+    CtZrtpStream *stream = streams[AudioStream];
+    int ret = stream->enrollAccepted(p);
+    setVerify(true);
+    return ret;
+}
+
+int CtZrtpSession::enrollDenied() {
+    if (!isReady || !(streams[AudioStream] != NULL))
+        return fail;
+
+    CtZrtpStream *stream = streams[AudioStream];
+    int ret = stream->enrollDenied();
+    setVerify(true);                        // TODO : Janis -> is that correct in this case?
+    return ret;
+}
+
+void CtZrtpSession::setClientId(std::string id) {
+    clientIdString = id;
+}
+
+bool CtZrtpSession::createSdes(char *cryptoString, size_t *maxLen, streamName streamNm, const sdesSuites suite) {
+
+    if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return fail;
+
+    CtZrtpStream *stream = streams[streamNm];
+    return stream->createSdes(cryptoString, maxLen, static_cast<ZrtpSdesStream::sdesSuites>(suite));
+}
+
+bool CtZrtpSession::parseSdes(char *recvCryptoStr, size_t recvLength, char *sendCryptoStr,
+                              size_t *sendLength, bool sipInvite, streamName streamNm) {
+
+    if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return fail;
+
+    CtZrtpStream *stream = streams[streamNm];
+    return stream->parseSdes(recvCryptoStr, recvLength, sendCryptoStr, sendLength, sipInvite);
+}
+
+bool CtZrtpSession::getSavedSdes(char *sendCryptoStr, size_t *sendLength, streamName streamNm) {
+    if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return fail;
+
+    CtZrtpStream *stream = streams[streamNm];
+    return stream->getSavedSdes(sendCryptoStr, sendLength);
+}
+
+bool CtZrtpSession::isSdesActive(streamName streamNm) {
+    if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return fail;
+
+    CtZrtpStream *stream = streams[streamNm];
+    return stream->isSdesActive();
+}
+
+int CtZrtpSession::getCryptoMixAttribute(char *algoNames, size_t length, streamName streamNm) {
+    if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return 0;
+
+    CtZrtpStream *stream = streams[streamNm];
+    return stream->getCryptoMixAttribute(algoNames, length);
+}
+
+bool CtZrtpSession::setCryptoMixAttribute(const char *algoNames, streamName streamNm) {
+    if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return fail;
+
+    CtZrtpStream *stream = streams[streamNm];
+    return stream->setCryptoMixAttribute(algoNames);
+}
+
+void CtZrtpSession::resetSdesContext(streamName streamNm, bool force) {
+    if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return;
+
+    CtZrtpStream *stream = streams[streamNm];
+    stream->resetSdesContext(force);
+}
+
+
+int32_t CtZrtpSession::getNumberSupportedVersions(streamName streamNm) {
+    if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return 0;
+
+    CtZrtpStream *stream = streams[streamNm];
+    return stream->getNumberSupportedVersions();
+}
+
+const char* CtZrtpSession::getZrtpEncapAttribute(streamName streamNm) {
+    if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return NULL;
+
+    CtZrtpStream *stream = streams[streamNm];
+    if (stream->isStopped)
+        return NULL;
+
+    return stream->getZrtpEncapAttribute();
+}
+
+void CtZrtpSession::setZrtpEncapAttribute(const char *attribute, streamName streamNm) {
+    if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+        return;
+
+    CtZrtpStream *stream = streams[streamNm];
+    if (stream->isStopped)
+        return;
+
+    stream->setZrtpEncapAttribute(attribute);
+}
+
+void CtZrtpSession::setAuxSecret(const unsigned char *secret, int length) {
+    if (!isReady || !(streams[AudioStream] != NULL))
+        return;
+
+    CtZrtpStream *stream = streams[AudioStream];
+    if (stream->isStopped)
+        return;
+
+    stream->setAuxSecret(secret, length);
+}
+
+void CtZrtpSession::cleanCache() {
+    getZidCacheInstance()->cleanup();
+}
+
+void CtZrtpSession::synchEnter() {
+    sessionLock.Lock();
+}
+
+void CtZrtpSession::synchLeave() {
+    sessionLock.Unlock();
+}